docs: fix audit-found drift (status enum, env, limitations, action layout)
Audit follow-up. ARCHITECTURE: status now 'In production', authoritative note that server actions are per-domain under lib/actions/* (no monolithic lib/actions.ts), rewrote stale Known Limitations (test suite exists; PayPal sync route; social auth wired; webhooks signing-only; single-space assumption), fixed env table (removed phantom SUPABASE_JWT_SECRET, added SECRETS_ENCRYPTION_KEY/OAuth). DATABASE_SCHEMA/DB_SCHEMA_MAP: ~43 tables / migrations through 038; space_members.status is member_status enum default 'unverified' (was wrongly 'active'); fixed the active/pending flow text. README: webhook wording matches WEBHOOKS.md. API_REFERENCE: real lib/actions/* path + 4 previously-undocumented actions. createSecret docs were already correct (ADMIN_ROLES = admin+board) -- left as-is.
This commit is contained in:
+2
-2
@@ -62,7 +62,7 @@
|
||||
| `email` | text | nullable |
|
||||
| `handle` | text | nullable |
|
||||
| `phone` | text | nullable |
|
||||
| `status` | text | default `'active'` |
|
||||
| `status` | member_status enum (`current`,`late`,`inactive`,`unverified`) | default `'unverified'`; "active" = `current`/`unverified`/`late` |
|
||||
| `payment_status` | text | nullable |
|
||||
| `payment_note` | text | nullable |
|
||||
| `joined_at` | timestamptz | |
|
||||
@@ -301,7 +301,7 @@ Default channels created by trigger on space INSERT: `general`, `announcements`,
|
||||
### Login
|
||||
1. `/login` → `signIn(email, password)` → Supabase auth
|
||||
2. Middleware checks session cookie
|
||||
3. App layout RSC calls `getCurrentMembership()` → queries `space_members` WHERE `user_id = auth.uid()` AND `status IN ('active', 'pending')`
|
||||
3. App layout RSC resolves the member → queries `space_members` WHERE `user_id = auth.uid()` AND `status IN ('current','unverified','late')` (the `ACTIVE_STATUSES` set in `lib/permissions.ts`)
|
||||
4. If no membership found → redirect `/signup`
|
||||
|
||||
### Dashboard
|
||||
|
||||
@@ -24,7 +24,7 @@ A multi-tenant operating system for hackerspaces, makerspaces, and member-run sh
|
||||
- **Governance.** Proposals with quorum, vote tracking and expiry; incident reports with anonymous reporter tracking by token; versioned policy library; member forum with polymorphic comments.
|
||||
- **Communications.** Multi-channel chat with realtime delivery.
|
||||
- **Recruitment.** Public-facing recruitment page per space.
|
||||
- **API.** PostgREST-generated REST for every table, gated by RLS. Optional webhooks with HMAC-signed deliveries.
|
||||
- **API.** PostgREST-generated REST for every table, gated by RLS. Webhook HMAC signing contract + secret rotation are defined; per-event delivery is a follow-up (see [docs/WEBHOOKS.md](./docs/WEBHOOKS.md)).
|
||||
|
||||
## Stack
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ async function joinSpace(formData: {
|
||||
|
||||
## 3. Task Actions
|
||||
|
||||
**File**: `lib/actions.ts`
|
||||
**File**: `lib/actions/tasks.ts` (server actions are split per-domain under `lib/actions/*.ts`, re-exported from `lib/actions/index.ts`; there is no monolithic `lib/actions.ts`)
|
||||
|
||||
### `createTask(formData)`
|
||||
|
||||
@@ -945,3 +945,9 @@ No permission code; any active member. All writes are self-only — the member i
|
||||
- `getMyVisits()` — the caller's own recent visits (the `/me` history).
|
||||
- `listAttendance()` — any member (org-wide attendance history is all-members by product decision); last 250 visits with computed status. No new permission code; managers are not special here.
|
||||
Surfaced as the "Who's here" panel on the dashboard (present list + self check-in/out + host + note), the `/attendance` page (all members), and "My recent visits" on `/me`.
|
||||
|
||||
### Previously-undocumented actions (audit addendum)
|
||||
- `updateMyProfile(input)` — `members.ts`; any member edits their own profile fields (self-scoped).
|
||||
- `discloseAffiliations(input)` — `members.ts`; the member records their own conflict-of-interest affiliations.
|
||||
- `updateSpaceVisibility(input)` — `settings.ts`; admin toggles space/member-directory visibility.
|
||||
- `listDoorCards(input)` — `door.ts`; `door.operate`, service client; active cards for a connection's grant/revoke UI, returning only the masked `last4` (raw UID never returned).
|
||||
|
||||
+20
-11
@@ -1,8 +1,15 @@
|
||||
# Hackerspace.sh - Architecture Documentation
|
||||
|
||||
> **Last Updated**: 2026-03-10
|
||||
> **Last Updated**: 2026-05-17
|
||||
> **Version**: 1.0.0
|
||||
> **Status**: Pre-Production Audit
|
||||
> **Status**: In production (serving live traffic)
|
||||
>
|
||||
> Note: Sections 7 and 13 and the project tree describe an earlier layout.
|
||||
> Server actions are split per-domain under `lib/actions/*.ts` (re-exported
|
||||
> from `lib/actions/index.ts`); there is no monolithic `lib/actions.ts`. The
|
||||
> per-module behavior is current; the module-feature sections later in this
|
||||
> document (Certifications, Classes, Equipment, Door, Presence, etc.) are the
|
||||
> authoritative reference.
|
||||
|
||||
---
|
||||
|
||||
@@ -395,7 +402,10 @@ Integration credentials stored in `integrations.config` (JSONB):
|
||||
| `NEXT_PUBLIC_SUPABASE_URL` | Yes | Supabase project URL |
|
||||
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Yes | Supabase anon key |
|
||||
| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Admin operations |
|
||||
| `SUPABASE_JWT_SECRET` | Yes | JWT verification |
|
||||
| `SECRETS_ENCRYPTION_KEY` | Yes | AES-256-GCM key for the secrets vault |
|
||||
| `NEXT_PUBLIC_OAUTH_GITHUB` / `NEXT_PUBLIC_OAUTH_GOOGLE` | No | Enable social sign-in buttons |
|
||||
|
||||
`.env.example` and `docs/DEPLOYMENT.md` are the authoritative env list. (`SUPABASE_JWT_SECRET` is not used by the app and was removed from this table.)
|
||||
|
||||
---
|
||||
|
||||
@@ -591,11 +601,10 @@ self-mark host. Surfaced as the dashboard "Who's here" panel, the
|
||||
|
||||
## 13. Known Limitations
|
||||
|
||||
1. **No test suite** - Unit, integration, and E2E tests needed
|
||||
2. **Payment integrations** - UI only, no actual OAuth/API
|
||||
3. **Import feature** - UI only, no file processing
|
||||
4. **Database connector** - UI only, not implemented
|
||||
5. **Social auth** - GitHub/Google buttons present but not wired
|
||||
6. **Webhook endpoint** - URL shown but no actual endpoint
|
||||
7. **Email notifications** - Not implemented
|
||||
8. **Search** - Client-side only, no full-text search
|
||||
1. **Test suite** - Extensive Vitest unit coverage of pure logic (`__tests__/`, run with `pnpm test`) plus Playwright smoke e2e (`e2e/`). Gap: server-action orchestration is not unit-tested (no Supabase mock harness); e2e is mostly page-render checks, not full write/RLS flows.
|
||||
2. **Payment integrations** - Manual import/CSV reconciliation is the primary path. A PayPal sync endpoint exists (`app/api/paypal/sync/route.ts`); Stripe/other live APIs are not integrated. See `docs/` and the Payments module section.
|
||||
3. **Social auth** - GitHub/Google sign-in is wired, gated by the `NEXT_PUBLIC_OAUTH_GITHUB`/`NEXT_PUBLIC_OAUTH_GOOGLE` env flags.
|
||||
4. **Webhooks** - The HMAC signing contract and secret rotation exist; per-event delivery is not implemented (see `docs/WEBHOOKS.md`).
|
||||
5. **Email notifications** - Not implemented.
|
||||
6. **Search** - Client-side filtering only, no server-side full-text search.
|
||||
7. **Single space per user** - The auth resolver assumes one active membership per user; a user in 2+ spaces is not supported (no space switcher). Fails closed.
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# Hackerspace.sh - Database Schema Reference
|
||||
|
||||
> **Last Updated**: 2026-05-15
|
||||
> **Last Updated**: 2026-05-17
|
||||
> **Database**: PostgreSQL via self-hosted Supabase
|
||||
> **Tables**: ~30
|
||||
> **Tables**: ~43
|
||||
> **Source of Truth**: `scripts/schema.sql` (canonical, idempotent); numbered
|
||||
> migrations `scripts/0NN_*.sql` upgrade existing deployments. The 13-table
|
||||
> reference below is the original baseline; tables added by migrations
|
||||
> 014-025 are summarized in the "Migrations 014-025" section at the end.
|
||||
> migrations `scripts/0NN_*.sql` (through **038**) upgrade existing
|
||||
> deployments. The 13-table reference below is the original baseline; tables
|
||||
> added by migrations 014-038 are summarized in the migrations section at the
|
||||
> end. `DB_SCHEMA_MAP.md` has the per-table quick map.
|
||||
|
||||
---
|
||||
|
||||
@@ -686,7 +687,7 @@ CREATE INDEX idx_activity_space ON activity_log(space_id, created_at);
|
||||
|
||||
---
|
||||
|
||||
## Migrations 014-035 (additions since the 13-table baseline)
|
||||
## Migrations 014-038 (additions since the 13-table baseline)
|
||||
|
||||
`scripts/schema.sql` is the canonical idempotent schema; each numbered
|
||||
migration is mirrored as a section in it. Tables/columns added:
|
||||
|
||||
Reference in New Issue
Block a user