Commit Graph

224 Commits (23089a9b1f40a677d24f4eac00b1ee2de0ddbb8f)
 

Author SHA1 Message Date
Thomas Joise 3d3487c85f wip(store-product): returns, GST returns, offline queue, security hardening + docs
Snapshot of the store-product workstream's in-progress work (apps/pos,
apps/backoffice, apps/store-server, packages): returns + credit notes, GST
returns exports, offline bill queue, rate-limiting, session policy, print
guard, batch tracking, and the SEC-C6/SEC-A5 auth fixes; plus docs/18 red-team
review. Committed to preserve work for the repo push. HQ console already
committed separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 4559958fa4 docs(hq): go-live runbook, env template and S3 backup script
Turnkey deployment for the AWS box: documented env vars, pm2/systemd run,
HTTPS reverse-proxy, nightly SQLite->S3 backup with rotation, and the Postgres
switch note. No secrets; unblocks go-live the moment the server/creds arrive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 5fe86f40ba chore(hq): demo-seed script + gitignore demo data/ruvector
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise cfa1cf81f6 feat(hq-web): DocumentView share & download action group
Add a Share & download group to DocumentView: Download PDF (hits
?download=1 via a bearer-authed blob + save anchor), Create/Copy a public
/share/<token> view link with the live-share list and one-click Revoke,
Share on WhatsApp (wa.me/<client digits> prefilled with greeting + doc no
+ total + the share link), and native share (navigator.share of the link,
falling back to Download where unsupported).

Client api.ts gains the Share type, shares on getDocumentFull, createShare/
revokeShare, and downloadDocumentPdf. Vite dev proxies /share to the hq
server so a minted link opens against the dev origin exactly as in prod
(the hq server serves both the SPA and the public /share route on one
origin). Server share/download endpoints and the golden renderer are
unchanged.

Browser-verified: minted a link, opened /share/<token> in a fresh
unauthenticated context (200 application/pdf, viewer renders the doc),
revoked and confirmed a 404 "Link unavailable" page with no data leak, and
confirmed the WhatsApp deep link is prefilled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 25b96e2514 feat(hq): attachment download filename on GET /documents/:id/pdf?download=1
Serve the document PDF as an attachment with a doc-no-derived filename
("QT/26-27-0001" -> "QT-26-27-0001.pdf", null docNo -> "draft.pdf") when
?download=1 is present; keep the default inline so the composer iframe
preview still works. renderPdf is now injectable into apiRouter so the
header logic is tested without launching Chrome (house DI pattern).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 63e377d649 feat(hq): public GET /share/:token document view route
Mount the one unauthenticated read route OUTSIDE the /api auth router.
A live token resolves via validateShare to exactly one document, rendered
inline (application/pdf) through the existing documentHtml -> renderPdf path;
unknown/expired/revoked tokens return a plain 404 "link expired or invalid"
HTML page carrying no document data. Adds a dependency-free per-IP fixed-window
rate limiter to blunt token brute-forcing. renderPdf is injected so the route
is TDD-tested without launching Chrome. Public reads write no audit; the token
is never logged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise a1759864bf feat(hq): shareable document link backend (mint/validate/revoke/list)
Add document_share table (CREATE TABLE IF NOT EXISTS; opaque token, optional
expiry, revoke flag) and repos-shares.ts:

- mintShare: 256-bit randomBytes hex token (64 hex, unique), default +30d expiry,
  audited — the token itself is never written to the audit trail or any log.
- validateShare: resolves a live token to its one document; null on
  unknown / revoked / expired (ISO-8601 UTC lexical compare).
- revokeShare: flips revoked=1, audited.
- listShares: a document's shares, scoped and newest-first.

Wire POST /api/documents/:id/share and
POST /api/documents/:id/share/:shareId/revoke (requireAuth, document-scoped
share guard) and surface shares on GET /api/documents/:id. TDD: 14 tests cover
token shape/uniqueness, validate rejections, revoke, and audit-without-token.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise d29025189c feat(hq): beautify document template — "Slate Ledger" visual system + template.accent
Rewrite documentHtml to a restrained, print-first GST layout: hairline table
rules, tabular money aligned to the paisa, a single accent driving every
structural color (letterhead rule, title, table-header rule + color-mix tint,
docmeta edge, amount-in-words edge, filled grand-total band).

Add optional template.accent setting (validated hex-or-fallback #334155
slate-indigo) read from the settings map and interpolated only after
validation, so a raw setting string can never be injected into the CSS.
print-color-adjust:exact so the accent tint and grand-total fill survive
puppeteer. DRAFT stays: accent chip in docmeta + optional watermark for
un-issued docs. lineRow/totalsRows untouched; @media screen paper + @page
14mm preserved; renderer stays one pure function so preview===pdf identity holds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 0d57c267ca feat(hq-web): reminder email preview in the manual queue
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 8212a9d898 docs: quotation polish + share/download design (beautify, tokenised share link, whatsapp, native share)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 0b340fd85f feat(hq-web): module quote-content live print preview
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise b65e03e1c4 feat(hq-web): Document Template page — editable letterhead data + live preview
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 08e067c7cc feat(hq-web): composer split view — server-truth totals strip, live paper, responsive
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise c2eb7acba0 feat(hq-web): LivePreview — debounced double-buffer iframe + preview fetchers
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 52e8a03c81 feat(hq): GET /reminders/:id/preview — exact email via shared reminderContext
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 48731fdb2b feat(hq): GET/PUT /settings/template + logo upload (owner-gated, audited)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise c2f94df06d feat(hq): screen paper styles + documentHtmlSample + POST /previews/sample
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise a948a92350 feat(hq): render editable template.* letterhead fields with default fallback
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 1ac44ae7de test(hq): golden fidelity — preview HTML byte-identical to the PDF's HTML
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 268a7469d3 feat(hq): POST /documents/preview — permissive live preview, persists nothing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 90df8b0e9f feat(hq): extract pure prepareDraft from createDraft (permissive preview path)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 7afd769a14 docs: live preview plan (13 tasks) + editable template-data scope in spec
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise 152545555e docs: live document preview design (approved via ultracode panel)
Same-code preview endpoint (no drift), form+A4-paper split layout, server-truth
totals strip, permissive-preview/strict-save, + company-letterhead / quote-content /
reminder-email sibling previews. Store-product surfaces documented as handoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 week ago
Thomas Joise dbccb8f954 feat(hq-web): owner company profile editor and client 360 aws usage trend
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 2acca18fc9 feat(hq-web): reports page — dues aging, module revenue, profitability, aws cost chart
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 5495b42e30 feat(hq): schedule monthly aws cost pull and owner-gated manual pull route
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise ea8c2b23ad feat(hq): company profile settings — owner-gated GET/PUT, audited
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise b7085ce56e feat(hq): payment receipts — own RCT/ series, zero-GST acknowledgment PDF
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 42cfa3d0b2 feat(hq): reports — dues aging, module revenue, client profitability with margin
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 51732df5e5 feat(hq): aws cost explorer ingestion — sigv4 signer and monthly tag-grouped pull
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 9d2eedc366 feat(hq): aws usage repo — upsert/list, cross-client cost ranking, routes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 3a09feab6f feat(hq): hq-3a schema — aws_usage table (per client per month)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 8267ef9257 docs: HQ-3a implementation plan (10 TDD tasks — reports, AWS costs, receipts, company profile)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 92fb5e6245 feat(hq-web): client 360 recurring, amc and interaction sections
Browser-walk fixes (Task 12 step 3): reload the reminder queue after a failed send so the row flips to 'failed' live, and reload AMC contracts after recording a payment so the Paid badge derives fresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise a9f78c4e3c feat(hq-web): client 360 recurring, amc and interaction sections
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 9e3886d0be feat(hq-web): dashboard money view with manual reminder queue as default route
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 06b5eb532c feat(hq): dashboard money view and 6-hourly scheduler wiring
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 7e1dcc1ad8 feat(hq): mailbox bounce detection with email_bounced reminders
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 1b14e49d86 feat(hq): recurring invoice generation with at-most-once auto-send
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 2d3b1a52a9 feat(hq): daily scan detection rules with idempotent reminders
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 3204a9af97 feat(hq): reminder email send reusing gmail, plus manual-queue routes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise a5f6b6fdaf feat(hq): reminder templates and idempotent reminder repo
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 868fe17a5d feat(hq): interaction log with types, follow-ups and routes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 0e66bd8ff8 feat(hq): amc contracts with renewal invoice and derived paid state
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 405ee2917f feat(hq): recurring plan repo and owner-gated routes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise c6a8058430 feat(hq): hq-2 schema — recurring/amc/interaction/reminder tables + bounce column + seeds
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise ea0bc146bb docs(security): SEC-A5 — /bills/offline commits bills with no authentication
Automated review (CRITICAL): route registered above requireAuth, identity
fields trusted from the body. Two fix options specified; must land before
any pilot. Companion to SEC-C6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 1523ebbcce docs: HQ-2 implementation plan (12 TDD tasks — reminders, recurring, AMC, dashboard)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 507eec67f3 docs(security): SEC-C6 — override approval is client-asserted, audit forgery hole
Automated review flagged POST /api/bills trusting overrides[].approvedByUserId
from the client; verify-pin result never bound to the commit. Server-side
approval-token fix specified; must land before any pilot (Phase 1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago
Thomas Joise 406839659d chore: bring the full store-product codebase under version control
POS, back office, store-server, all packages, workspace configs, README/
BUILDING, and the WIP HQ-2 plan — everything except gitignored data
(client import staging, .env, local DBs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago