--- id: VERGABE-WP-0019 type: workplan title: "Admit the first invited company pilot with protected access and recoverable data" domain: communication repo: vergabe-teilnahme status: active owner: the-custodian topic_slug: vergabe-teilnahme created: "2026-09-11" updated: "2026-09-11" related: [VERGABE-WP-0018, RAPPS-WP-0014, HFACT-WP-0001] --- # Invited company pilot ## Confirm the bounded customer milestone ```task id: VERGABE-WP-0019-T01 status: done priority: high assignee: the-custodian ``` User decision on 2026-09-11: start with an invited pilot, one company and several users, manually onboarded. Pricing is a later improvement and is not an entry gate. Use the existing single-company product: each admitted company has an isolated deployment, database and data volumes. All active company members can collaborate on the company's tenders; the existing v1 domain approval roles remain descriptive. Django staff/superuser administration remains restricted. External partners remain data objects. No public registration or shared-app multitenancy is introduced. Product readiness proceeds alongside the governed factory runtime. It does not wait for the fourteen-day factory value study. VERGABE-WP-0018-T03 retains the separate claim that the factory can produce and deliver the customer release; HFACT-WP-0001-T05 still needs a natural governed worker trace. ## Require invited access across the UI and uploaded documents ```task id: VERGABE-WP-0019-T02 status: done priority: high assignee: the-custodian ``` Use Django's default-deny login middleware with explicit health/login exemptions, German login and password-change forms, CSRF-protected POST logout, and full-page reauthentication for expired HTMX sessions. Protect uploaded files in production and development, serve private attachments only within MEDIA_ROOT, and keep operational issue state outside that downloadable root. Do not cache company responses. Inactive users lose existing session access; ordinary members do not gain Django administration privileges. The 12 access regressions initially produced 9 failures, including actual anonymous tender read/create. After the fix all 94 application tests pass locally and in the existing container target; Vite assets build, 139 static files collect, and migration drift is absent. New/changed access modules pass Ruff. Source acceptance is not native customer admission. ## Publish and prove the isolated deployment and recovery contract ```task id: VERGABE-WP-0019-T03 status: progress priority: high assignee: the-custodian depends_on: [VERGABE-WP-0019-T02, RAPPS-WP-0014-T02, RAPPS-WP-0014-T03] ``` RAPPS-WP-0014 owns exact image/chart/host/namespace/database/Secret binding, persistent media plus distinct issue-facade state, isolated restore rehearsal, and rollback. The customer app owns live CI and immutable release evidence. Obtain the exact company, user count, hostname and empty-vs-existing data choice from the user; no password or user list is required in public work records. The historical vergabe_db is not disposable and must not be overwritten. On 2026-09-11 the checked Railiance cluster contains neither the historical vergabe-teilnahme namespace nor any Deployment whose name/image contains vergabe/teilnahme. Treat the old runbook as historical intent, not a live return. Native placement and existing data inventory remain required before cutover. ## Accept onboarding, collaboration, recovery and support with pilot users ```task id: VERGABE-WP-0019-T04 status: wait priority: high assignee: the-custodian depends_on: [VERGABE-WP-0019-T03] blocking_reason: "Await admitted company deployment, immutable release and demonstrated restore; company/host/data selection is pending." ``` Product acceptance: Bernd Worsch and the named company contact. Verify two separate ordinary-user accounts can sign in, change passwords, create a tender and lot, collaborate on tasks, upload/download a document, record a v1 domain approval and submission, and report feedback. Verify anonymous access and a revoked user fail, health remains available, and pod replacement preserves all three data stores. Restore a backup into an isolated destination and repeat the workflow without touching the live database. Record operator/support contact, incident route, backup cadence/retention and demonstrated recovery time. Use manual account creation/reset/deactivation through the admitted operator path; never seed development accounts or put credentials in logs/workplans/chat. A successful invited pilot does not claim shared multitenancy, paid subscriptions, HA or autonomous production release. Pricing is outside this milestone and will need a later explicit product decision.