Moheeb Zara 9447b5ee80 feat: customizable permissions, per-item Ops ACLs, area-lead roles
Migration 023 (folded into schema.sql section 15). ADDITIVE and
backward compatible: with no permission/ACL rows the app behaves
exactly as before.

Schema:
- space_role_permissions (space_id, subject, permission); ops_acl
  (space_id, entity_type secret|kb|process|area_lead, entity_id,
  role). Full RLS, writes admin/board.
- user_effective_roles(uid,sid): built-in role + custom-role slugs +
  area_lead:<id> for areas the member leads. SECURITY DEFINER.
- user_has_permission(uid,sid,perm): admin implicit-all else a grant
  via an effective role. SECURITY DEFINER.
- secrets/knowledge_base SELECT rewritten as
  `exact existing rule OR ops_acl match` (only widens; zero change
  with no ACL rows). Seed + backfill default role permissions.

Area-lead roles reuse the existing area_leads table rather than
duplicating the concept: a row is a role, lead_id NULL = Vacant,
assigning sets lead_id, the member then holds area_lead:<id>.

App:
- lib/permissions-catalog.ts (codes + per-role defaults + guardrails),
  Zod schemas, lib/actions/permissions.ts (setRolePermissions,
  setOpsAcl, createAreaLeadRole, assign/unassign/delete).
- Customize gains Permissions (role x permission matrix, admin shown
  implicit-all/locked) and Area leads (create/Vacant/assign) panels,
  modular under customize/panels/. Reusable
  components/ops/ops-acl-editor.tsx wired into the Secrets list.

Audit-found latent fixes:
- revealSecret errors on encrypted-but-no-ciphertext corruption
  instead of silently returning the stale plaintext column.
- upsertAreaLead rejects null/empty area_code (NULLs are distinct in
  unique constraints; allowed duplicate rows).

types/database.ts: added the two new tables. 271/271 tests pass,
build clean. KB-modal ACL wiring + members-row shortcut deferred and
tracked in HANDOFF.
2026-05-15 17:15:14 -07:00
2026-03-11 04:44:48 +00:00
2026-03-11 04:44:48 +00:00
2026-03-11 04:44:48 +00:00
2026-03-11 04:44:48 +00:00
2026-03-11 08:00:22 +00:00

hackerspace-management

License: MIT Next.js Supabase

A multi-tenant operating system for hackerspaces, makerspaces, and member-run shops. One installation can host many independent spaces. Each space owns its own members, tasks, projects, payments, knowledge base, proposals, incidents, policies, and chat channels. All data access is enforced at the database with row-level security.

Features

  • Members and tiers. Roster, tiers (Plus, Basic, Associate), roles (admin, board, treasurer, member, associate), state (current, late, inactive, unverified), per-member skills, certifications, and badges.
  • Tasks and projects. Project boards, task assignment, status, area tagging, priority, comments.
  • Operations. Knowledge base, secrets vault, area leads, equipment, maintenance log.
  • Payments and financials. Per-member payment ledger, integration credentials per space, exports, monthly financial summary.
  • Governance. Proposals with vote tracking and expiry, incident reports, policy library, area-of-interest configuration.
  • 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.

Stack

Layer Technology
App Next.js 16, React 19, TypeScript, Tailwind v4, shadcn/ui
Data PostgreSQL 17 via self-hosted Supabase
Auth Supabase GoTrue, JWT, email + password
Realtime Supabase Realtime (Phoenix channels over WebSocket)
Storage Block volume on the host (database), local FS (uploads)
Email Resend (SMTP)
Reverse proxy Caddy 2 (automatic Let's Encrypt)
Tests Vitest (unit), Playwright (end to end)

Quick start (local development)

Requirements: Node.js 20 or later, pnpm 10 or later, Docker (for the local Supabase CLI), git.

git clone https://github.com/virgilvox/hackerspace-management.git
cd hackerspace-management
pnpm install
cp .env.example .env.local

Edit .env.local with values from your local Supabase project (see docs/LOCAL_DEV.md to start one in seconds using the Supabase CLI), then:

pnpm dev

Open http://localhost:3000, sign up, create a space, you land on the dashboard.

Detailed local setup: docs/LOCAL_DEV.md.

Production deployment

The supported production target is a single DigitalOcean Droplet running self-hosted Supabase plus the Next.js app behind Caddy with Let's Encrypt. No managed Supabase, no third-party application data store.

End-to-end guide: docs/DEPLOY_DO_SELFHOSTED.md.

Summary:

  1. Provision a Droplet (4 GB RAM, 2 vCPU, 80 GB disk recommended).
  2. Attach a block volume mounted at /mnt/data for the Postgres data directory and backups.
  3. Point DNS A records for your domain, www, supabase, studio at the Droplet.
  4. Run the bootstrap script in scripts/ to install Docker, Supabase, Node, Caddy, the app, the systemd unit, backup cron, and the deploy hook.
  5. Push to main. GitHub Actions runs deploy.sh on the Droplet over SSH: pull, install, apply pending migrations, build, restart.

The deploy script is idempotent and tracked: every numbered migration in scripts/ is recorded in public._migrations_applied. New migrations are applied automatically on push.

Database

scripts/schema.sql is the canonical, idempotent, full schema. Run it once on a fresh Supabase project. Subsequent changes are added as numbered migrations (scripts/021_*.sql, 022_*.sql, etc.) and applied incrementally.

Topic Doc
Conventions scripts/README.md
Full reference docs/DATABASE_SCHEMA.md
Column map DB_SCHEMA_MAP.md

Documentation

File Contents
docs/ARCHITECTURE.md System design, project structure, auth flow
docs/DATABASE_SCHEMA.md Tables, enums, indexes, RLS policies
docs/API_REFERENCE.md Server actions and REST endpoints
docs/COMPONENT_REFERENCE.md UI components and props
docs/DEPLOY_DO_SELFHOSTED.md End to end production deploy
docs/LOCAL_DEV.md Fresh clone to running locally
docs/GOVERNANCE_FEATURES.md Proposals, incidents, policies
docs/WEBHOOKS.md Webhook payload, signing, verification
TESTING.md Test commands and coverage
CONTRIBUTING.md How to contribute
CHANGELOG.md Notable changes per release
SECURITY.md Vulnerability disclosure
LICENSE MIT

Scripts

pnpm dev          # development server
pnpm build        # production build
pnpm start        # serve production build
pnpm lint         # eslint
pnpm test         # vitest watch mode
pnpm test:ui      # vitest UI
pnpm test:e2e     # playwright end-to-end

Project status

The system is feature-functional and serving production traffic at hackerspace.sh. See docs/AUDIT.md for the latest audit and the open issues list.

Contributing

Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request. Security issues: see SECURITY.md.

License

MIT. See LICENSE.

S
Description
No description provided
Readme MIT
3.8 MiB
Languages
TypeScript 89.7%
PLpgSQL 6.4%
CSS 1.8%
JavaScript 1.3%
Shell 0.7%
Other 0.1%