[2] Storage-backed LawNet BFF and frontend #37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Objective
Build the BFF and frontend around an explicit storage contract so LawNet catalog and case-detail screens can run against either local mock files or PostgreSQL.
This slice is intentionally limited to the web/BFF product surface and the storage boundary. It should make frontend work debuggable without Docker Compose or PostgreSQL, while still defining the PostgreSQL-backed contract that later ingestion work will write to.
Dependencies
Depends on #36.
Scope
Out of scope
Done when
[2] LawNet catalog MVPto [2] Storage-backed LawNet BFF and frontendImplementation plan
This issue is planning-only for the BFF/frontend/storage-contract slice. Do not implement LawNet live ingestion here.
Core goal
Build the LawNet catalog and case-detail product surface through a storage abstraction that can run against either local mock files or PostgreSQL.
The implementation should deliver:
Important design decision
Use class-based dependency injection, not a backend parameter passed through every function.
Define a shared interface and inject an implementation at the server boundary:
Concrete classes:
Factory:
API/query handlers should receive or create a
LawNetStorageinstance and call the common interface. Do not threadstorageBackendorusePostgresstyle parameters through individual methods.Proposed file layout
All storage/config modules should import
@tanstack/react-start/server-onlyso they cannot enter the client bundle.Environment variables
Use one explicit backend selector:
Allowed values:
Recommended defaults:
pnpm dev: default tofilesystem.postgres.postgresrequiresDATABASE_URL.filesystemusesLAWNET_FILE_STORAGE_ROOT, defaulting to./mock/lawnetfromservices/web.Add to
.env.example:Pass both through the web service in
compose.yaml.Storage contract types
Use typed nullable fields so malformed/incomplete records remain visible.
Recommended enum unions:
Summary fields:
Detail fields:
Do not expose raw source payloads through the public BFF in this issue.
Case IDs and artifact IDs
Treat IDs as opaque at the API/frontend boundary.
Recommended:
caseId = base64url(sourceKey).PostgreSQL schema
Add
services/flyway/sql/V2__lawnet_storage.sql.Recommended first-cut tables:
Add indexes for list/detail queries:
Decision: store first-cut Postgres artifact bytes in
bytea. This keeps #37 self-contained and avoids premature object-storage or host-volume design.Filesystem storage
Use:
The JSON should mirror the storage contract rather than the final LawNet API.
Security requirements:
...LAWNET_FILE_STORAGE_ROOT.404for missing files.Postgres storage
Use
pg, already present inservices/web/package.json.Implementation requirements:
DATABASE_URL.postgres-storage.server.ts.decision_date DESC NULLS LAST, thensource_key ASC.Pagination:
limitdefault:50.limitmax:100.cursorshould be opaque.nextCursor, notoffset.BFF API routes
Add:
GET /api/lawnet/casesresponse:Supported query params:
qcan be simple in #37:ILIKEover citation/title/case number.GET /api/lawnet/cases/$caseIdresponse:Return
404when unknown.GET /api/lawnet/artifacts/$artifactId:Content-Typefrom metadata.Content-Disposition: attachment; filename="...".X-Content-Type-Options: nosniff.404when unknown.Do not render raw HTML artifacts inline in this issue.
Frontend routes
Add:
Dashboard requirements:
/lawnet/$caseId.Detail page requirements:
recordStatusandissueSummaryprominently when present.dangerouslySetInnerHTML.The
/route may remain a landing page and link to/lawnet.Tests
Minimum useful coverage:
WEB_TEST_DATABASE_URL.404behavior.Avoid adding heavy browser test dependencies in this issue unless necessary.
Verification commands
Run at least:
If migrations are changed, also verify Flyway through the existing project workflow.
Explicitly out of scope
Do not implement in #37:
Agreed decisions
bytea.pnpm devshould default to filesystem storage.Split into three subtasks:
/debugdashboard and case‑detail pages, lightweight debug UI.