Grow the Pics Portal from a read-only browse tool into a full-surface client portal that replaces SSI/Strawbridge's PlicGo / Captura School Portal for our customers — subjects management, exports, print layouts, and customer-facing access. Shipped in four phases so each unlocks value on its own.
Goals
Be the system of work for everything a school-photography studio does with shoot data after capture: organize subjects, dedupe rosters, ship SIS exports, print IDs and badges, share files with schools.
Reach feature parity with the PlicGo / Captura incumbent on the four-tab surface (Subjects / Download Exports / Print Layouts / Files) so customer migration is a non-event.
Open the portal to customers (schools, district admins) directly — not just Pics admins — under real RBAC.
Keep authoring tools first-class. Studios must be able to create their own custom exports and their own print layouts without Pics-team involvement.
Hold the cost of operation low. One Next.js app, Supabase, a job substrate, and a render service. No second backend service unless we measurably need one.
Non-goals
Not a photographer-facing capture tool. Capture, sales, and order fulfillment stay in Pics.
Not a yearbook designer. We render templated ID-card-style layouts; we don't compete with InDesign or Pixami.
Not a parent storefront. Consumer ordering is out of scope.
Not a Pics replacement. Pics stays the system of record for capture-time data (studios, venues, events, photos).
No mobile apps in v1. Responsive web only.
Personas
Pics admin (us)
Has super_admin in Pics. Onboards studios, debugs data, has all permissions across studios.
Studio admin
Owns a Pics company / studio. Manages venues, events, subject rosters, exports, layouts, and invites customer users.
Studio operator
Day-to-day employee of a studio: imports subjects, runs exports, prints IDs. Permission-scoped to specific projects or to the whole studio.
Customer (school) admin
A principal, registrar, or yearbook coordinator at a school. Lives outside Pics's user model — needs portal-only identity. Reviews their school's subjects, approves rosters, downloads their school's exports, uploads files in response to requests.
Customer (school) user
A teacher or staff member who needs to upload a roster CSV or check a directory. Lowest-privilege role.
Four-phase roadmap
Phase 1 — Subjects + Exports core next
Goal: Studios can manage subjects for an event, find duplicates, generate the subject directory, and run the 25 standard SIS exports — end-to-end.
Subject model with a stable core + extensible custom-fields, per event.
Layout authoring: canvas-based editor (or chosen alternative — see open question) with image slots, text fields with %FieldName% bindings, layout asset uploads.
Version + duplicate flow on both formats and layouts.
Non-goals for Phase 3: Public layout marketplace, cross-studio sharing.
Phase 4 — Customer portal + RBAC + Files
Goal: Schools log in to their own scoped view of the portal. Studios send file requests; customers respond.
Studio / Client / User / Role taxonomy (Geskus-shaped) with per-client scope.
Customer auth (decision pending — see open questions).
Customer-facing routes: scoped subject view, file requests inbox, completed exports / prints visible to the assigned school.
File request workflow: studio creates request → customer uploads → status transitions → notification email.
Non-goals for Phase 4: Self-serve studio onboarding, public sign-up. All customer accounts are invite-driven from a studio.
Cross-cutting concerns
Scale
School-photography studios handle 10⁵–10⁶ subjects and image variants per season at the high end. Two implications:
Every list endpoint must paginate (cursor where possible). Every bulk operation must be async.
Image references stay as URLs / signed-URL fetches — we never load full image binaries through Next.js server actions on the request path.
Async job model
Exports, subject-directory PDFs, layout renders, and bulk subject imports are all async with progress UI. They share one job substrate. The substrate choice is an open ADR; whatever we pick must support: enqueue from a Next.js server action, worker concurrency control, status polling endpoint, per-job progress percentage or step counter, output artifact handoff (signed URL).
RBAC
Phase 4 introduces real RBAC, but Phases 1–3 lay groundwork: every entity we add (subject, export job, layout, render job) is tagged with a studio_id (and where appropriate, a client_id / school scope) so the Phase 4 permission filter is a single query parameter, not a refactor.
Subjects as the load-bearing entity
Subjects are referenced by exports, the subject directory, the print wizard, find-duplicates, file requests, and (eventually) customer scoping. The subject schema and storage decision is the single highest-leverage decision in the whole project — captured as a dedicated ADR after the Phase 1 PRD is reviewed.
Image strategy
Today Pics serves images through some mechanism we don't yet consume. Print rendering needs full-resolution images; export "Named Images" formats need original files. We need a clearly-defined image-access contract with Pics before Phase 2 can start. ADR pending.
Customer auth
The four candidates (magic-link, Auth0, Pics SSO with delegated identity, provision Pics accounts) each have different operational and ergonomic implications. Decision required before Phase 4. ADR pending.
Success metrics
Phase 1: a real studio runs a full event (import subjects → dedupe → directory → one standard export) without engineering hand-holding.
Phase 2: a real studio renders a multi-page ID-card PDF that's acceptable for production printing.
Phase 3: a studio authors a new custom export and a new layout without Pics-team involvement. Time-from-need-to-first-export under 30 minutes.
Phase 4: a school user logs in, sees only their school's data, responds to a file request, and downloads their roster. Studios issue zero "can you send me your data?" emails.
Operational: 99th-percentile export job under N minutes (set per phase); render PDFs reproducible across re-runs; zero subject-data divergence between Pics and the portal.
Sequencing rationale
Phase 1 is the data foundation. Everything downstream (layouts, custom exports, customer scoping) needs subjects in place.
Phase 2 (render-only) before Phase 3 (authoring) lets us validate the render pipeline against existing layouts before opening the authoring surface.
Phase 3 bundles custom exports + layout authoring because both reuse the "structured authoring + studio-scoped persistence" pattern. Designing one tells us how to design the other.
Phase 4 last because RBAC over an evolving feature set is much harder than RBAC over a stable one.
What's not in this document
Detailed feature specs — those live in the per-phase PRDs. Phase 1 PRD →
Architectural decisions — recorded as ADRs once Phase 1 PRD is reviewed.
Implementation breakdown — Phase 1 impl plan and Linear epic to follow.