Skip to content

Scaffold: fold auth into the default template as a gallery card, remove saas template #993

Description

@vivek7405

Problem

There are two UI scaffolds that are largely the same: the default full-stack template and --template saas. The saas template is essentially the default (layout, gallery, db wiring) PLUS auth (login/signup, session, a protected dashboard, a User model). Maintaining a whole second template that is mostly a duplicate is drift-prone, and auth is a browsable concept a learner would reach for like any other feature.

Design / approach

Collapse to ONE UI template. Add a self-contained auth gallery feature card to the default template (a login / session / protected-route demo, prunable like every other card via gallery:clear), and remove the separate --template saas.

Decision rationale: this is the lean grow-in-place direction the scaffold already took (single-source skill, gallery:clear, post-#971). Auth-as-a-card teaches the concept without forcing a whole separate template.

DECIDED (owner): the auth card is NOT just a browsable demo, it WIRES A REAL PROTECTED ROUTE so a fresh default app keeps the saas "auth already wired in" baseline. So the card ships: a users table in db/schema.server.ts, createAuth() config, login/signup pages, session wiring, AND a genuinely protected route (a middleware.ts gate or a page-level auth() / unauthorized() check that redirects an anonymous visitor to login). Pruning it via gallery:clear removes the whole auth surface (card, modules, the users table, the protected route) back to the minimal base, the same way the demo todos table is dropped today. This gives one template that is minimal by default but carries a real, promotable auth baseline, replacing what --template saas did. Breaking change to webjs create --template saas, acceptable since WebJs has no users yet (no back-compat burden).

Implementation notes (for the implementing agent)

  • Where to edit:
    • Template handling + saas wiring: packages/cli/lib/create.js (template dispatch) and packages/cli/lib/saas-template.js (remove, or fold its auth pieces into the new gallery card). The --template flag + help text in packages/cli/bin/webjs.js (the create usage around L163, and the create handler around L878).
    • New gallery card: packages/cli/templates/gallery/app/features/auth/ + packages/cli/templates/gallery/modules/auth/ (login/session/protected demo). Register in the FEATURES array (create.js ~L1340).
    • gallery:clear: add the new auth module to the galleryModules list in packages/cli/templates/scripts/clear-gallery.mjs so the card is pruned like the rest. NOTE the current clear script has a comment about KEEPING saas auth modules; once saas is removed, reconcile that.
    • Tests: test/scaffolds/gallery-coverage.test.js generates all THREE templates today (['full-stack','api','saas'] around L185) plus scaffold-*.test.js; drop saas from those and add coverage for the auth card. The createAuth / Credentials / Google / GitHub server exports are demoed today only by the saas template, so they move into the coverage picture via the new card or need re-classification in test/scaffolds/gallery-coverage.json.
    • Docs: grep --template saas / saas across docs/, website/, README.md, AGENTS.md, and packages/cli/templates/** agent rule files and update every mention (invoke webjs-doc-sync + webjs-scaffold-sync).
  • Landmines: removing a template is a coordinated change across generator + tests + docs + coverage manifest; a stale saas reference will red the scaffold suites. The auth server exports MUST stay demonstrated somewhere or gallery-coverage.test.js fails. The gallery ships in every UI template; generators emit strings, so verify by generating + booting a fresh app.
  • Invariants: default to a real database (Drizzle + SQLite); server-only code behind .server.ts; PE-safe login form (a no-JS <form> posting to a page action or route). Light DOM + Tailwind.
  • Upgrade the server-actions greet demo's auth middleware (shipped in PR feat: add webjs-frame gallery demo and rework the server-actions demo #989, packages/cli/templates/gallery/modules/server-actions/middleware/require-auth.server.ts) to the real session: replace the signedOut-from-input hack with await getCurrentUser(ctx.request) reading the signed session cookie (which rides the same-origin RPC POST, so no wrapping segment middleware is needed), and drop the signedOut flag from greet.server.ts + the checkbox in components/greeter.ts. The ctx.context.user -> actionContext().user handoff and the 401 short-circuit are unchanged; only the identity source swaps, and the 401 becomes real (an anonymous caller is genuinely denied). The demo was deliberately shaped for this swap.
  • Consider bundling the smaller gallery gaps from the same audit as follow-ups or into this work: a lazy static lazy component demo, HTTP-verb action caching missing from the UI caching demo (app/features/caching/, taught only in the api template today), and no shipped readiness.ts template.

Acceptance criteria

  • The default template ships auth wired in: a users table, createAuth(), login/signup pages, session wiring, AND a genuinely protected route that redirects an anonymous visitor to login (an authenticated visitor reaches it)
  • gallery:clear removes the entire auth surface (card, modules, users table, protected route) back to the minimal base, verified by a fresh generate + clear + webjs check
  • --template saas is removed; webjs create offers one UI template (plus api)
  • The auth-related @webjsdev/server exports stay demonstrated (coverage manifest green)
  • All docs / agent rule files / README mentioning saas are updated
  • Scaffold suites updated (no saas generation) and green; generate + boot + webjs check on a fresh app pass

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions