Commit Graph

3 Commits

Author SHA1 Message Date
noroot
77de1627c5 feat: add mobile-first styling matching enconf's CI
Pages were unstyled HTML until now. design/enterprise.css (enconf's
4400-line stylesheet) is tightly coupled to Ant Design/React class
names and a fixed desktop sidebar layout — not usable as-is for
Deklarix's plain server-rendered forms. Instead, internal/web/static/
app.css is a small, purpose-built mobile-first stylesheet that reuses
enconf's actual design tokens (primary blue #1677ff, radius scale,
shadows, Inter) for brand consistency without dragging in the
unrelated layout/framework rules.

Inter is self-hosted (copied from enconf's font files) rather than
pulled from Google Fonts, keeping the "no runtime internet dependency"
property. Only the "latin" subset is included — German umlauts and ß
all live in U+0000-00FF, so the cyrillic/greek/vietnamese subsets
enconf ships aren't needed here.

Inputs/buttons are sized for touch (44px min-height) and use 16px font
size to avoid iOS's auto-zoom-on-focus. Findings are color-coded by
severity (red/amber/green backgrounds with a matching left border).

Verified visually with chromium --headless --screenshot at both mobile
(390px) and desktop (1280px) viewports, including a real WK-001 finding
fetched from the running server and rendered through the actual
stylesheet — not just asserted via HTTP status codes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:41:57 +02:00
noroot
5156fe62da feat: wire auth into the web layer (Schritt 2, part 2/2)
Registration creates a new account plus its first user; login
authenticates an existing one; both set a deklarix_session cookie
(HttpOnly, SameSite=Strict, Secure only when the request itself came
over TLS — hardcoding Secure=true would break local http://localhost
development, since browsers won't store a Secure cookie over plaintext).

requirePage protects full-page GETs (redirects to /login); requireAPI
protects the htmx/download endpoints (401, since those are only ever
called from an already-authenticated page — an unauthenticated hit
there is the exception, e.g. a session expiring mid-use).

handleCheck now creates submissions under the current account.
handleArchive and handleDossierDownload compare the submission's
account against the caller's and return 404 on mismatch — not 403,
which would confirm the ID exists to a different tenant. Login failure
uses the same message for "no such email" and "wrong password" to avoid
account enumeration.

Restructured templates along the way: layout.html now only holds
reusable fragments ("head", "nav"); each full page (index/login/register)
is its own top-level named template. The previous layout+content nesting
would have broken the moment a second page defined "content" — Go's
html/template keys blocks by name across the whole parsed set, not per
file, so two pages both defining "content" would silently overwrite each
other.

Verified against a real running instance (not just Go's test recorder):
started the compiled binary against a fresh Postgres and drove the whole
flow with curl — anonymous redirect, registration setting a real cookie,
authenticated page load, logout clearing both the cookie and the
server-side session row, and being locked out again afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 15:56:11 +02:00
noroot
31caa8f66a feat: add web layer (internal/web) and wire it into main.go
Routing, html/template layout/content pattern, and the Pre-Publish
check flow: POST /pruefen runs extraction (Stufe 1) then rules.Evaluate
(Stufe 2) and renders the result as an htmx fragment. Nothing is
persisted yet — that's the next step (wiring internal/store in).

The needsClarification case is rendered explicitly as a request for
more information rather than "no findings", matching the core
principle. Every result carries the legal-advice disclaimer required by
CLAUDE.md's guardrails.

Server depends on a narrow Extractor interface rather than *extract.
Client directly, so tests inject a fake instead of calling the real API
— internal/web's test suite never touches the network. htmx is vendored
locally (internal/web/static/htmx.min.js) instead of loaded from a CDN,
keeping the UI usable without runtime internet access.

cmd/deklarix/main.go now wires all of this together: reads
ANTHROPIC_API_KEY (required) and RULES_DIR (default "rules"), builds
the extract client and loads the rule set, and serves web.Server instead
of the old inline health-only mux.

This exposed the same crash-loop risk fixed earlier for DATABASE_URL:
postinst's start guard only checked DATABASE_URL, so a fresh install
would now crash-loop on a missing ANTHROPIC_API_KEY instead. The guard
checks both. scripts/build.sh also now ships rules/*.yaml into the .deb
under /usr/share/deklarix/rules (not a conffile — rules are updated via
the release pipeline, never hand-edited on a server), and
deklarix.env.example points RULES_DIR there by default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 14:23:45 +02:00