ソースを参照

feat(docs): add initial project documentation and backlog structure

Code_Uwe 2 週間 前
コミット
34a9b81e39
8 ファイル変更915 行追加0 行削除
  1. 64 0
      AGENTS.md
  2. 25 0
      Docs/PLANS.md
  3. 52 0
      Docs/SPEC.md
  4. 33 0
      Docs/STATUS.md
  5. 53 0
      Docs/decisions.md
  6. 686 0
      Docs/tickets.md
  7. 1 0
      reviews/.gitkeep
  8. 1 0
      reviews/archive/.gitkeep

+ 64 - 0
AGENTS.md

@@ -0,0 +1,64 @@
+# rhl-lieferscheine
+
+## Tech Stack
+- Frontend: Next.js 16 App Router, React 19, JavaScript/JSX, Tailwind CSS 4
+- Backend: Next.js Route Handlers on Node.js 22-slim
+- Database: MongoDB 7 via Mongoose 9
+- Auth: Signed JWT session cookie (`auth_session`), `bcryptjs`, RBAC roles `branch | admin | superadmin | dev`
+- Deployment: Docker Compose with NAS mount, GitLab CI/CD planned
+
+## Conventions
+- Read `~/.codex/docs/NEXTJS_CONVENTIONS.md` for code conventions.
+- Read `~/.codex/docs/DEFAULT_STACK.md` for stack defaults.
+
+## Project-Specific Rules
+- Keep owner-facing conversation in German.
+- Write source code, comments, tests, and project docs in English.
+- Keep user-facing UI text in German.
+- Treat `Docs/` as the canonical project documentation directory for this repository.
+- Do not overwrite existing `Docs/` content without explicit approval. `Docs/frontend-ui.md` may contain local changes and must stay untouched unless the user asks for edits there.
+- Keep the product scope intentionally pragmatic. Do not reintroduce dropped feature families such as large dashboards, saved searches/bookmarks, or an in-app PDF viewer without approval.
+- Treat Qsirch as required for the target environment. Do not plan production rollout around filesystem search alone.
+- Respect the current access model: one account per branch, branch users only see their own branch, elevated roles may work across branches, and only `superadmin` / `dev` may manage users.
+- Follow the established delivery flow: work ticket-by-ticket, run `npx vitest run` and `npm run build` before new implementation steps, stop for local/server verification before updating docs.
+- When docs are requested, write full-file outputs instead of diff snippets.
+
+## Ticket Naming
+- Prefix: RHL
+- Format: `RHL-XXX`
+
+## Branch And MR Naming
+- Branch: `type/rhl-xxx-slug`
+- MR title: `RHL-XXX type(scope): summary`
+- Types: feat, fix, refactor, docs, chore, style, test, perf, ci, build
+
+## Commands
+- Install dependencies: `npm install`
+- Start dev server: `npm run dev`
+- Run tests once: `npx vitest run`
+- Watch tests: `npm run test:watch`
+- Build production bundle: `npm run build`
+- Start production server: `npm run start`
+- Lint repository: `npm run lint -- .`
+- Validate environment: `node scripts/validate-env.mjs`
+- Start local Docker stack: `docker compose -f docker-compose.yml -f docker-compose.local.yml up --build`
+- Start server-like Docker stack: `ENV_FILE=.env.server docker compose -f docker-compose.yml up -d --build`
+- Run manual API smoke flow: `docker compose exec app node scripts/manual-api-client-flow.mjs --baseUrl=http://127.0.0.1:3000 --username=<user> --password=<pw> --branch=<branch>`
+
+## Key Paths
+- `app/` - routes, protected/public app structure, route handlers
+- `components/` - UI building blocks
+- `lib/` - domain logic, API client helpers, auth/storage/search helpers
+- `models/` - MongoDB user model
+- `scripts/validate-env.mjs` - environment validation entrypoint
+- `scripts/manual-api-client-flow.mjs` - manual smoke validation helper
+- `Docs/` - existing product and operational documentation
+- `docker-compose.yml` and `docker-compose.local.yml` - runtime definitions
+
+## Stop And Ask
+Escalate before continuing when the task touches:
+- architecture or scope changes
+- auth, RBAC, or security-sensitive behavior
+- database schema or MongoDB operational topology
+- CI/CD, deployment automation, reverse proxy, or HTTPS rollout
+- secrets, credentials, or Qsirch integration details

+ 25 - 0
Docs/PLANS.md

@@ -0,0 +1,25 @@
+# Project Plans
+
+## Current Phase
+- Phase: pre-launch v2 hardening and rollout preparation
+- Goal: replace the currently used v1 with a more reliable and operationally safer v2
+
+## Known Direction
+- Move the repository into GitLab and establish a repeatable CI/CD pipeline.
+- Introduce HTTPS via reverse proxy so secure cookie-based authentication works without workarounds.
+- Harden MongoDB and auth-related security paths for production rollout.
+- Add basic operational observability without turning the project into an oversized platform effort.
+- Keep UI and DX polish focused on proven user value.
+
+## Near-Term Priorities
+- `RHL-011` Production HTTPS and reverse proxy
+- `RHL-031` Backend auth security hardening
+- `RHL-010` CI/CD workflow
+- `RHL-013` MongoDB hardening and production settings
+- `RHL-014` Observability, logging, and basic monitoring
+- If infrastructure work is blocked, fall back to `RHL-039`, `RHL-036`, `RHL-035`, `RHL-033`, `RHL-034`, and `RHL-040`
+
+## Future Considerations
+- `RHL-028` admin UX scaling only if real daily pain points appear.
+- Password Reset Phase B if there is a real business need for a token/email-based reset flow.
+- Any environment model beyond `main` and `production` should stay minimal and justified.

+ 52 - 0
Docs/SPEC.md

@@ -0,0 +1,52 @@
+# rhl-lieferscheine - Specification
+
+## Goals
+- Replace the currently used v1 with a more reliable v2 for internal delivery note access.
+- Let branch users find and open delivery note PDFs quickly through explorer and search flows.
+- Provide controlled cross-branch access and user management for privileged roles.
+
+## Target Users
+- Primary: branch staff who need to retrieve delivery note PDFs for their own branch.
+- Secondary: admin, superadmin, and developer/support users who oversee delivery note operations and manage accounts.
+
+## Core Features (as-built)
+1. Cookie-based authentication with role-aware access, logout/session handling, and enforced password change when required.
+2. Branch/year/month/day explorer flow with breadcrumbs and dedicated empty, loading, error, forbidden, and not-found states.
+3. Search with branch scopes, date filters, cursor pagination, recent-search history, and navigation back into explorer context.
+4. PDF open/download flow from both explorer and search.
+5. Profile page with password-change flow and support contact.
+6. User management for privileged roles, including create, edit, delete, search, and temporary password reset.
+7. Overview home cards that route users into the main application areas.
+
+## Known Limitations
+- v2 is not live yet; release and deployment are still largely manual.
+- GitLab migration/setup, CI/CD, HTTPS/reverse proxy, MongoDB hardening, and observability are still open work areas.
+- There is no separate staging/test server environment yet.
+- The production-ready search experience depends on Qsirch being available and configured.
+
+## Non-Goals
+- A large dashboard with new-document or last-seen behavior.
+- Saved searches/bookmarks as a major product feature.
+- An in-app PDF viewer.
+- Feature expansion without a clear operational need.
+
+## Constraints
+- The application is internal to a multi-branch company and must enforce branch-level isolation for standard users.
+- Each branch currently works with one shared branch account; privileged admin-like roles are individual accounts.
+- Delivery note PDFs are scanned externally and deposited onto the NAS folder tree used by the app.
+- User-facing UI remains German, while code, tests, and docs remain English.
+- URL state is the source of truth for explorer and search navigation.
+- Documentation updates happen after successful verification, not before.
+
+## Technical Architecture
+- Next.js 16 App Router application using route handlers under `app/api/*`.
+- React 19 client shell around protected/public routes.
+- MongoDB-backed user model managed through Mongoose.
+- Signed JWT session cookie authentication with RBAC checks in the application layer.
+- NAS-backed document browsing plus Qsirch-backed indexed search for the target environment.
+- Docker Compose runtime with separate local-fixture and server-like NAS mount behavior.
+
+## Open Questions
+- The exact GitLab project migration and branch/environment automation flow are still TBD.
+- The concrete monitoring and alerting stack is still TBD.
+- The final production release checklist after HTTPS and CI/CD rollout is still TBD.

+ 33 - 0
Docs/STATUS.md

@@ -0,0 +1,33 @@
+# Project Status
+
+## Codex Onboarding
+- Onboarded: 2026-04-16
+- Prior work accepted as-is. Codex tracking begins from this date.
+
+## Current State
+- Phase: pre-launch active development for the v2 rollout
+- Last updated: 2026-04-16
+- Current branch: RHL-Audit
+
+## Pre-Onboarding Context
+- v1 is already live and used internally, but it is considered inadequate compared with the current v2 target.
+- v2 already covers the main user journeys: authentication, explorer navigation, search, PDF access, profile management, and privileged user management.
+- Remaining work is concentrated in deployment, operations, security hardening, and selected polish items.
+
+## Currently In Progress
+- None. Codex onboarding is complete; the next step is to start from an approved backlog ticket.
+
+## Completed
+- None since Codex onboarding started on 2026-04-16.
+
+## Known Issues
+- None tracked by Codex yet.
+
+## Recent Decisions
+- 2026-04-16 Treat Qsirch-backed search as required for the target environment - see `Docs/decisions.md`
+- 2026-04-16 Keep the product intentionally pragmatic and avoid previously dropped feature families - see `Docs/decisions.md`
+- 2026-04-16 Integrate Codex artifacts into `Docs/` and preserve existing project docs - see `Docs/decisions.md`
+
+## Next Steps
+- Create the GitLab project and define the intended `main` and `production` environment model.
+- Choose the first implementation ticket from the onboarding backlog based on infrastructure readiness and business priority.

+ 53 - 0
Docs/decisions.md

@@ -0,0 +1,53 @@
+# Decisions Log
+
+> Decisions extracted during Codex onboarding on 2026-04-16.
+> These reflect the current state of the project as understood from the approved onboarding summary and owner interview.
+
+## Decision: Next.js App Router on a JavaScript-only stack
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: The project is maintained by a single developer and aims to deliver an internal tool quickly without adding unnecessary platform overhead.
+- Decision: Build the application on Next.js 16 App Router, React 19, JavaScript/JSX, Tailwind CSS 4, and MongoDB/Mongoose.
+- Tradeoffs: The stack stays lightweight and productive, but it relies on discipline rather than TypeScript-level static guarantees.
+
+## Decision: Cookie-based JWT sessions with branch-aware RBAC
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: Branch users must be restricted to their own documents, while privileged roles need broader operational access.
+- Decision: Use a signed JWT session cookie (`auth_session`) together with RBAC roles `branch`, `admin`, `superadmin`, and `dev`.
+- Tradeoffs: The model matches the business structure well, but it makes HTTPS, auth hardening, and careful permission checks operationally important.
+
+## Decision: Model the product around the existing NAS folder hierarchy
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: Delivery note PDFs are scanned outside the application and written directly into branch/year/month/day folders on the NAS.
+- Decision: Keep explorer navigation and path-based document access aligned with the NAS hierarchy instead of introducing an additional document abstraction layer.
+- Tradeoffs: The application stays close to the real storage model, but it is tightly coupled to path conventions and NAS availability.
+
+## Decision: Keep explorer and search navigation URL-driven
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: The owner wants predictable navigation, shareable deep links, and a simple state model.
+- Decision: Treat the URL as the source of truth for explorer and search state.
+- Tradeoffs: Deep-linking stays straightforward, but UI state changes must stay carefully synchronized with routing behavior.
+
+## Decision: Keep the product scope intentionally pragmatic
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: The application should solve the core delivery-note retrieval problem without overwhelming users or stretching a one-developer project.
+- Decision: Focus on login, scoped access, explorer, search, PDF open, profile/password management, and privileged user management. Keep large dashboards, saved searches/bookmarks, and an in-app PDF viewer out of scope unless explicitly re-approved.
+- Tradeoffs: The product stays lean and easier to ship, but some convenience features are intentionally deferred or dropped.
+
+## Decision: Treat Qsirch as required for the target environment
+- Status: adopted (pre-Codex)
+- Date: pre-onboarding
+- Context: The current v1 search experience is too slow without indexed search, and v2 is expected to fix that.
+- Decision: Treat Qsirch as a required production-facing dependency rather than an optional enhancement.
+- Tradeoffs: Search performance improves, but the rollout depends on Qsirch availability, credentials, and operational setup.
+
+## Decision: Integrate Codex artifacts into the existing `Docs/` tree
+- Status: approved
+- Date: 2026-04-16
+- Context: The repository already contains established documentation in `Docs/`, and `Docs/frontend-ui.md` currently has local changes that must not be disturbed.
+- Decision: Write Codex onboarding artifacts into `Docs/` and leave existing project documentation untouched unless explicitly requested.
+- Tradeoffs: Historical and Codex-generated documentation now coexist in one directory, so future updates must stay disciplined to avoid drift.

+ 686 - 0
Docs/tickets.md

@@ -0,0 +1,686 @@
+# Backlog
+
+> Codex onboarding: 2026-04-16
+> Ticket prefix: RHL
+> This backlog tracks work from the onboarding date forward.
+> Prior implementation work is accepted as-is and not retroactively tracked.
+> The entries below were carried into Codex onboarding from the existing pre-Codex planning backlog.
+
+---
+
+## RHL-010: CI/CD workflow
+Status: draft
+
+### Intent
+- **User Story:** As a developer, I want automated build, test, and deployment steps so that changes can be rolled out reproducibly and with less manual risk.
+- **Purpose:** Replace the current manual Docker rebuild/update flow with a minimal but reliable GitLab-oriented delivery pipeline.
+
+### Acceptance Criteria
+1. WHEN tracked branches are pushed THEN the system SHALL install dependencies, run `npx vitest run`, and run `npm run build`.
+2. WHEN a deployment is triggered for the agreed target environment THEN the system SHALL build the Docker image and document the deployment path.
+3. WHEN a deployment completes THEN the project SHALL provide a simple smoke verification path and updated operational docs.
+
+### Constraints
+- **Business Rules:** The branch/environment model should align with the intended `main` and `production` split.
+- **Non-Functional:** Prefer a minimal, understandable pipeline over multi-environment overengineering.
+- **Boundaries:**
+  - Always do: keep the flow GitLab-compatible and keep manual verification explicit.
+  - Ask first: container registry choice, deployment automation mechanism, and environment topology.
+  - Never do: introduce blue/green, canary, or a large platform redesign without approval.
+
+### Design Hints
+- **Files Likely Affected:** `.gitlab-ci.yml`, `Dockerfile`, `docker-compose.yml`, `Docs/runbook.md`, `Docs/STATUS.md`, `Docs/PLANS.md`
+
+### Dependencies
+- Depends on: GitLab project setup and target-environment agreement
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-011: Production HTTPS and reverse proxy
+Status: draft
+
+### Intent
+- **User Story:** As a user, I want to access the application over HTTPS so that cookie-based sessions work safely in production.
+- **Purpose:** Introduce a minimal reverse-proxy/TLS setup that removes the need for insecure HTTP cookie workarounds.
+
+### Acceptance Criteria
+1. WHEN the production-facing deployment is opened THEN the application SHALL be reachable over HTTPS with HTTP redirected to HTTPS.
+2. WHEN users log in over the HTTPS setup THEN secure cookies SHALL work without setting `SESSION_COOKIE_SECURE=false`.
+3. WHEN the release setup is verified THEN login, explorer, search, and PDF open SHALL complete successfully over HTTPS.
+
+### Constraints
+- **Business Rules:** The production path should remain simple enough for an internal deployment.
+- **Non-Functional:** Keep the proxy setup minimal and avoid headers or proxy rules that break PDF behavior.
+- **Boundaries:**
+  - Always do: validate cookie behavior end-to-end.
+  - Ask first: reverse-proxy choice, certificate strategy, and host naming.
+  - Never do: introduce Kubernetes or an oversized ingress stack without approval.
+
+### Design Hints
+- **Files Likely Affected:** `docker-compose.yml`, server deployment config, `Docs/runbook.md`, future CI/CD docs
+
+### Dependencies
+- Depends on: target server and certificate/proxy decision
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-013: MongoDB hardening and production settings
+Status: draft
+
+### Intent
+- **User Story:** As an operator, I want MongoDB configured safely for production so that the application runs with least privilege and clear operational settings.
+- **Purpose:** Harden the database setup without turning it into a large infrastructure rewrite.
+
+### Acceptance Criteria
+1. WHEN the production MongoDB setup is reviewed THEN the project SHALL define and document a least-privilege application user.
+2. WHEN the compose/auth configuration is updated THEN the application SHALL continue to run with the hardened configuration.
+3. WHEN the work is complete THEN the required runtime connection data and operating notes SHALL be documented.
+
+### Constraints
+- **Business Rules:** Keep the current data model and application contract intact.
+- **Non-Functional:** Focus on practical hardening, not a database-platform overhaul.
+- **Boundaries:**
+  - Always do: preserve application compatibility and document the operating setup.
+  - Ask first: topology changes, backups, or operational changes outside the app's current footprint.
+  - Never do: redesign the persistence layer or migrate away from MongoDB without approval.
+
+### Design Hints
+- **Files Likely Affected:** `docker-compose.yml`, environment templates, `Docs/runbook.md`, deployment docs
+
+### Dependencies
+- Depends on: access to the target MongoDB deployment model
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-014: Observability, logging, and basic monitoring
+Status: draft
+
+### Intent
+- **User Story:** As an operator, I want logs and basic observability so that failures are easier to detect and analyze.
+- **Purpose:** Add a lightweight operational visibility baseline without starting an enterprise-monitoring program.
+
+### Acceptance Criteria
+1. WHEN important error paths occur THEN the relevant logs SHALL be consistent enough to trace the failure.
+2. WHEN operators need to inspect the application THEN the project SHALL define where to check logs and basic health information.
+3. WHEN the work is complete THEN the runbook SHALL describe the agreed logging/monitoring routine.
+
+### Constraints
+- **Business Rules:** Operational visibility must stay proportional to the size of the project.
+- **Non-Functional:** Prefer simple logging and health checks over a large monitoring stack no one uses.
+- **Boundaries:**
+  - Always do: keep the output actionable for local and server troubleshooting.
+  - Ask first: external monitoring providers or alerting integrations.
+  - Never do: introduce a large observability platform without approval.
+
+### Design Hints
+- **Files Likely Affected:** logging helpers under `lib/`, health endpoints, `Docs/runbook.md`, deployment docs
+
+### Dependencies
+- Depends on: chosen deployment topology
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-028: Frontend admin UX scaling
+Status: draft
+
+### Intent
+- **User Story:** As an admin-like user, I want branch-spanning search and navigation to remain clear when I work across many branches.
+- **Purpose:** Reassess remaining admin UX ideas and implement them only if they have proven daily value.
+
+### Acceptance Criteria
+1. WHEN the current admin UX is reviewed THEN the project SHALL either document that no change is needed or identify a clearly justified improvement.
+2. WHEN an improvement is implemented THEN search/grouping or admin-specific navigation SHALL become clearer without adding feature bloat.
+3. WHEN the ticket closes THEN the chosen outcome SHALL be documented as implemented, deferred, or left intentionally unchanged.
+
+### Constraints
+- **Business Rules:** Optional ticket; only proceed if the benefit is clear.
+- **Non-Functional:** Avoid UI churn that does not solve a real operational problem.
+- **Boundaries:**
+  - Always do: validate the need against actual admin workflows.
+  - Ask first: any broader product-scope expansion beyond focused UX improvement.
+  - Never do: add admin-only feature sprawl without approval.
+
+### Design Hints
+- **Files Likely Affected:** search UI under `app/` and `components/`, role-gated navigation
+
+### Dependencies
+- Depends on: real admin usage feedback
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-030: Frontend entry route behavior follow-up
+Status: draft
+
+### Intent
+- **User Story:** As a maintainer, I want the historical entry-route ticket reconciled with the current home/launcher behavior so that the backlog reflects reality.
+- **Purpose:** Review whether RHL-030 is fully superseded by RHL-046 or whether a small remaining gap still exists.
+
+### Acceptance Criteria
+1. WHEN the current `/` route behavior is reviewed THEN the project SHALL compare it against the original RHL-030 intent.
+2. WHEN no meaningful gap remains THEN the ticket SHALL be documented as superseded or merged into RHL-046.
+3. WHEN a small gap remains THEN the project SHALL restate the remaining scope clearly before implementation starts.
+
+### Constraints
+- **Business Rules:** This is primarily a backlog hygiene and scope-clarity task.
+- **Non-Functional:** Keep the outcome lightweight and traceable.
+- **Boundaries:**
+  - Always do: prefer closing or restating the ticket over carrying vague scope.
+  - Ask first: reopening larger entry-route work beyond the current launcher behavior.
+  - Never do: quietly revive superseded scope without approval.
+
+### Design Hints
+- **Files Likely Affected:** `Docs/tickets.md`, `Docs/PLANS.md`, home route documentation, potentially `app/(protected)/page.jsx`
+
+### Dependencies
+- Depends on: review of the current home-page behavior against historical intent
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-031: Backend auth security hardening
+Status: draft
+
+### Intent
+- **User Story:** As an operator, I want auth endpoints hardened so that brute-force attempts and obvious abuse are reduced.
+- **Purpose:** Add bounded security hardening to the authentication surface without mixing it with a larger password-reset project.
+
+### Acceptance Criteria
+1. WHEN login traffic hits the auth endpoints THEN the system SHALL enforce agreed rate limiting for at least the login path.
+2. WHEN security-relevant auth events occur THEN the project SHALL either log the agreed subset or document why additional audit logging is deferred.
+3. WHEN the ticket is complete THEN tests, verification steps, and docs SHALL cover the hardened behavior.
+
+### Constraints
+- **Business Rules:** Keep Password Reset Phase B explicitly out of scope.
+- **Non-Functional:** Security controls must be effective without breaking legitimate branch logins.
+- **Boundaries:**
+  - Always do: define the rate-limit policy explicitly.
+  - Ask first: any reset-flow, SMTP, or broader identity-management expansion.
+  - Never do: fold this ticket into a larger auth rewrite without approval.
+
+### Design Hints
+- **Files Likely Affected:** auth route handlers under `app/api/auth/*`, auth helpers under `lib/`, tests, operational docs
+
+### Dependencies
+- Depends on: agreement on rate-limit behavior and logging detail
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-033: Frontend explorer navigation caching and prefetch
+Status: draft
+
+### Intent
+- **User Story:** As a user, I want the explorer to feel faster and show less loading flicker while I navigate.
+- **Purpose:** Improve perceived responsiveness of the existing explorer flow with bounded client-side caching or prefetching.
+
+### Acceptance Criteria
+1. WHEN users move between explorer levels THEN the interface SHALL feel noticeably smoother than the current baseline.
+2. WHEN caching or prefetching is introduced THEN RBAC, error states, and stale-data handling SHALL remain correct.
+3. WHEN the implementation is complete THEN the chosen behavior SHALL be documented and covered by suitable regression checks.
+
+### Constraints
+- **Business Rules:** Keep the implementation proportionate to the value.
+- **Non-Functional:** Avoid introducing a complex caching framework for a narrow UX improvement.
+- **Boundaries:**
+  - Always do: preserve correctness around permissions and empty/error states.
+  - Ask first: new caching libraries or behavior that changes data freshness expectations materially.
+  - Never do: trade correctness for perceived speed without approval.
+
+### Design Hints
+- **Files Likely Affected:** explorer routes/components under `app/` and `components/`, fetch helpers under `lib/`
+
+### Dependencies
+- Depends on: -
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-034: Frontend skeleton and layout polish
+Status: draft
+
+### Intent
+- **User Story:** As a user, I want calmer loading states with less layout jumping so that navigation feels more stable.
+- **Purpose:** Tighten loading skeletons and layout consistency in a bounded, visible way.
+
+### Acceptance Criteria
+1. WHEN loading states are shown in explorer, search, or admin UI THEN skeleton dimensions SHALL remain stable enough to reduce layout jitter.
+2. WHEN the polish work is complete THEN loading and layout patterns SHALL feel visually consistent across the touched areas.
+3. WHEN regression checks run THEN the UI SHALL remain functionally unchanged apart from the intended polish.
+
+### Constraints
+- **Business Rules:** Stop once the visible benefit is achieved.
+- **Non-Functional:** Avoid endless cosmetic iteration without measurable UX value.
+- **Boundaries:**
+  - Always do: target user-facing jitter and consistency issues directly.
+  - Ask first: larger visual redesign ideas beyond the scoped polish.
+  - Never do: turn this ticket into a broader re-theme without approval.
+
+### Design Hints
+- **Files Likely Affected:** loading/skeleton components, explorer/search/admin layout components, relevant route UI files
+
+### Dependencies
+- Depends on: -
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-035: Chore - Node warning and tooling cleanup
+Status: draft
+
+### Intent
+- **User Story:** As a developer, I want recurring tooling warnings handled cleanly so that real problems stand out faster.
+- **Purpose:** Investigate and resolve the existing Node/tooling warning noise without destabilizing the repository.
+
+### Acceptance Criteria
+1. WHEN the current warning is analyzed THEN the project SHALL either remove it or document clearly why it remains acceptable for now.
+2. WHEN any module-format or tooling change is applied THEN build and test behavior SHALL remain stable.
+3. WHEN the ticket closes THEN the chosen ESM/CJS approach SHALL be explicit enough to avoid confusion.
+
+### Constraints
+- **Business Rules:** Keep the fix proportional to the warning.
+- **Non-Functional:** Avoid broad repository churn for a narrow cleanup item.
+- **Boundaries:**
+  - Always do: validate the effect on local runtime, tests, and build output.
+  - Ask first: any repo-wide module-format migration.
+  - Never do: introduce a large structural refactor just to silence a warning.
+
+### Design Hints
+- **Files Likely Affected:** `package.json`, tooling config files, scripts, docs if warning remains documented
+
+### Dependencies
+- Depends on: -
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-036: Search smoke test script
+Status: draft
+
+### Intent
+- **User Story:** As a developer, I want a small reproducible smoke script for search and PDF flows so that key behavior can be checked quickly.
+- **Purpose:** Add a focused validation script without introducing a full end-to-end framework for this need.
+
+### Acceptance Criteria
+1. WHEN the smoke script runs THEN it SHALL cover login, search page 1, cursor page 2, and PDF open/download or HEAD checks.
+2. WHEN RBAC-negative scenarios are executed THEN the script SHALL verify the expected protected behavior.
+3. WHEN the work is complete THEN usage and prerequisites SHALL be documented.
+
+### Constraints
+- **Business Rules:** Keep the script easy to run for local and server verification.
+- **Non-Functional:** Prefer a lightweight script over a full E2E harness for this ticket.
+- **Boundaries:**
+  - Always do: keep the checks deterministic and reproducible.
+  - Ask first: converting this into a larger browser-based test suite.
+  - Never do: add a heavy E2E stack solely for this smoke path without approval.
+
+### Design Hints
+- **Files Likely Affected:** `scripts/`, API helpers, `Docs/runbook.md`, developer docs
+
+### Dependencies
+- Depends on: available test user and environment data
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-039: Test noise reduction for expected error paths
+Status: draft
+
+### Intent
+- **User Story:** As a developer, I want quieter test and CI output so that real failures are easier to spot.
+- **Purpose:** Silence expected stderr/`console.error` noise in tests without hiding genuine problems.
+
+### Acceptance Criteria
+1. WHEN expected error-path tests run THEN the noisy log output SHALL be suppressed in a targeted way.
+2. WHEN unexpected failures happen THEN the relevant error signals SHALL still surface clearly.
+3. WHEN the ticket closes THEN the test suite SHALL stay green with noticeably cleaner output.
+
+### Constraints
+- **Business Rules:** Test clarity matters more than blanket suppression.
+- **Non-Functional:** The production logging behavior must remain intact.
+- **Boundaries:**
+  - Always do: scope mocking/silencing to expected test cases.
+  - Ask first: production-code changes that alter runtime logging semantics.
+  - Never do: hide real production or test failures behind broad suppression.
+
+### Design Hints
+- **Files Likely Affected:** Vitest setup/helpers, error-path tests, logging helpers if test-only hooks are needed
+
+### Dependencies
+- Depends on: identification of the noisy tests
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-040: Docs consistency check
+Status: draft
+
+### Intent
+- **User Story:** As a developer, I want the documentation to reflect the real product state so that future work starts from accurate references.
+- **Purpose:** Audit for stale "planned" or "coming soon" statements and update only the docs that are actually outdated.
+
+### Acceptance Criteria
+1. WHEN the documentation is reviewed THEN outdated claims about current functionality SHALL be identified.
+2. WHEN stale content is confirmed THEN the affected docs SHALL be updated to match the implemented product state.
+3. WHEN the ticket closes THEN the touched docs SHALL be consistent with the actual application behavior.
+
+### Constraints
+- **Business Rules:** Focus on real drift, not editorial rewriting for its own sake.
+- **Non-Functional:** Keep the scope targeted and evidence-based.
+- **Boundaries:**
+  - Always do: update only the docs that are demonstrably stale.
+  - Ask first: broad documentation restructuring.
+  - Never do: rewrite the entire docs tree without a specific need.
+
+### Design Hints
+- **Files Likely Affected:** `Docs/*.md`, `README.md`, future Codex docs as needed
+
+### Dependencies
+- Depends on: confirmed application behavior
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-047: GitLab project bootstrap and repository migration
+Status: draft
+
+### Intent
+- **User Story:** As a maintainer, I want this repository moved and operational in GitLab so that all future delivery work runs through the new GitLab workflow instead of the legacy Git server.
+- **Purpose:** Establish GitLab as the canonical remote, including the minimal repository governance needed to support clean collaboration, CI, and later deployment automation.
+
+### Acceptance Criteria
+1. GIVEN the project still depends on the legacy Git server WHEN the migration is completed THEN GitLab SHALL be the canonical remote for the repository and the team SHALL have a documented migration path.
+2. GIVEN the new GitLab project exists WHEN branch governance is configured THEN the repository SHALL define the baseline protected-branch and merge-request rules needed for safe delivery.
+3. GIVEN the target delivery flow depends on GitLab CI/CD WHEN the bootstrap is completed THEN the repository SHALL document the required runner baseline and project-level CI/CD prerequisites.
+
+### Constraints
+- **Business Rules:** GitLab becomes the source of truth for future work on v2.
+- **Non-Functional:** Keep the initial setup pragmatic and minimal; avoid overengineering the project settings.
+- **Boundaries:**
+  - Always do: document the canonical remote, branch policy, and minimum GitLab project settings.
+  - Ask first: access model, group/project location, runner ownership, and whether import or fresh remote push is preferred.
+  - Never do: silently change production deployment behavior as part of the repository migration alone.
+
+### Implementation Context
+- **Affected Files:** `Docs/runbook.md` (GitLab-based operational flow), `Docs/STATUS.md` (project state), `Docs/PLANS.md` (near-term direction), optionally `README.md` if clone/remote instructions are updated.
+- **Reuse:** Reuse the current Docker-based runtime and runbook separation between local and server-like operation.
+- **New:** GitLab project settings, remote migration procedure, protected-branch baseline, merge-request baseline, runner prerequisites documentation.
+- **Framework Notes:** Keep the repository layout unchanged; this ticket is primarily repo governance and documentation, not application feature work.
+
+### Dependencies
+- Depends on: -
+- Blocks: RHL-048, RHL-049, RHL-050
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-048: GitLab CI quality gate for merges
+Status: draft
+
+### Intent
+- **User Story:** As a maintainer, I want GitLab to block bad merges automatically so that broken code does not enter the main integration branch.
+- **Purpose:** Introduce a merge-request quality gate that verifies the project builds and tests successfully before code is merged.
+
+### Acceptance Criteria
+1. GIVEN a merge request targets `main` WHEN the pipeline runs THEN GitLab SHALL execute the agreed validation steps, at minimum `npm install`, `npx vitest run`, and `npm run build`.
+2. GIVEN any required validation job fails WHEN a merge request is reviewed THEN GitLab SHALL block merge into `main`.
+3. GIVEN the pipeline is configured WHEN maintainers inspect the project docs THEN the required CI behavior, job scope, and local preflight commands SHALL be documented.
+
+### Constraints
+- **Business Rules:** The quality gate should protect merges into `main`, not rely only on post-merge detection.
+- **Non-Functional:** Keep CI understandable and reproducible from local commands.
+- **Boundaries:**
+  - Always do: align CI commands with existing package scripts and repository tooling.
+  - Ask first: whether lint must become required immediately and whether any cache or image optimization is desired in the first version.
+  - Never do: add broad deployment logic into the merge-quality ticket.
+
+### Implementation Context
+- **Affected Files:** `.gitlab-ci.yml` (new), `package.json` (only if command normalization is needed), `Dockerfile` (if CI build strategy needs alignment), `Docs/runbook.md`, `Docs/STATUS.md`, `Docs/PLANS.md`.
+- **Reuse:** Reuse the existing commands `npx vitest run`, `npm run build`, and `node scripts/validate-env.mjs` where useful.
+- **New:** GitLab CI pipeline definition, required pipeline stages, MR blocking policy, documentation for local-vs-CI validation parity.
+- **Framework Notes:** Prefer the simplest GitLab pipeline that mirrors current repo commands; do not introduce a custom build system.
+
+### Dependencies
+- Depends on: RHL-047
+- Blocks: RHL-049, RHL-050
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-049: Staging deployment automation from main
+Status: draft
+
+### Intent
+- **User Story:** As a maintainer, I want the integrated `main` branch deployed automatically to a non-user-facing staging environment so that I can verify real server behavior before promoting releases.
+- **Purpose:** Create a server-side staging path that is separate from production and suitable for internal validation with real infrastructure constraints.
+
+### Acceptance Criteria
+1. GIVEN changes are merged into `main` WHEN the staging deployment pipeline runs successfully THEN the staging environment SHALL update automatically from `main`.
+2. GIVEN staging is used for internal validation WHEN the environment is configured THEN it SHALL remain separate from production in URL and access and SHALL not be the environment used by end users.
+3. GIVEN the staging environment uses production-like infrastructure WHEN the deployment is defined THEN the project SHALL document the required environment variables, NAS/Qsirch expectations, and the database isolation strategy from production.
+4. GIVEN a staging deployment completes WHEN verification runs THEN the project SHALL provide an explicit smoke-check flow for login, explorer, search, and PDF access.
+
+### Constraints
+- **Business Rules:** Staging is for internal testing and release validation, not for end users.
+- **Non-Functional:** Production and staging must not share mutable application data blindly; especially the database setup needs explicit separation.
+- **Boundaries:**
+  - Always do: separate staging from production by environment configuration and deployment target behavior.
+  - Ask first: exact hostnames, server topology, whether staging and production share one host, and how secrets are provisioned.
+  - Never do: point staging at the production database without explicit approval.
+
+### Implementation Context
+- **Affected Files:** `.gitlab-ci.yml`, `docker-compose.yml`, potential server-specific compose override, `Docs/runbook.md`, `Docs/STATUS.md`, `Docs/PLANS.md`.
+- **Reuse:** Reuse the current Docker Compose runtime, `ENV_FILE` pattern, and smoke validation flow described in `Docs/runbook.md`.
+- **New:** staging deployment job, staging environment documentation, deployment target conventions, server-side environment separation rules.
+- **Framework Notes:** Prefer a simple deployment mechanism first; GitLab-triggered SSH deployment is acceptable if it is the smallest reliable path.
+
+### Dependencies
+- Depends on: RHL-047, RHL-048
+- Blocks: RHL-050
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing
+
+## RHL-050: Production release flow and tagged deployment automation
+Status: draft
+
+### Intent
+- **User Story:** As a maintainer, I want production deployments to happen only through an explicit release flow so that end users only receive intentionally promoted versions.
+- **Purpose:** Define and automate the final production release path, including branch promotion, release tagging, Docker build/publish, and server deployment.
+
+### Acceptance Criteria
+1. GIVEN staging validation is complete WHEN maintainers promote the release THEN the workflow SHALL require an explicit production promotion step instead of auto-deploying every `main` change to users.
+2. GIVEN the agreed production flow uses the `production` branch and release tags WHEN a production release is triggered THEN GitLab SHALL build and deploy the production artifact from that approved release event.
+3. GIVEN a production release completes WHEN operators verify the rollout THEN the project SHALL document the release, rollback, and post-deploy smoke-check procedure.
+4. GIVEN production deployment is automated WHEN credentials and deploy logic are configured THEN the project SHALL use a documented and reviewable mechanism for server access and secret handling.
+
+### Constraints
+- **Business Rules:** Production remains a consciously promoted environment for real users.
+- **Non-Functional:** Release automation must be auditable and reversible.
+- **Boundaries:**
+  - Always do: require an explicit promotion or release step before production deploy.
+  - Ask first: final release trigger model, image registry choice, SSH key handling, and rollback expectations.
+  - Never do: deploy production directly from unreviewed feature branches or from every `main` merge.
+
+### Implementation Context
+- **Affected Files:** `.gitlab-ci.yml`, `docker-compose.yml`, possible deployment helper scripts, `Docs/runbook.md`, `Docs/STATUS.md`, `Docs/PLANS.md`, release/process docs.
+- **Reuse:** Reuse the Docker image build path, existing server runtime assumptions, and the staging smoke-validation flow as the basis for production checks.
+- **New:** production promotion logic, release-tag trigger flow, production deployment job, rollback/release documentation, credential-handling guidance.
+- **Framework Notes:** Keep the first production automation path pragmatic and reviewable; an SSH-based GitLab deployment is acceptable if it is the clearest operational baseline.
+
+### Dependencies
+- Depends on: RHL-047, RHL-048, RHL-049
+- Blocks: -
+
+### Exit Criteria
+- [ ] All acceptance criteria pass
+- [ ] Tests present and passing
+- [ ] No open security findings
+
+### Sub-Tasks (added by implementer)
+
+### Quality Gates
+- [ ] Code Review
+- [ ] Security Review (if applicable)
+- [ ] Tests passing

+ 1 - 0
reviews/.gitkeep

@@ -0,0 +1 @@
+

+ 1 - 0
reviews/archive/.gitkeep

@@ -0,0 +1 @@
+