From cd286e7ac5f492ee97ad25aaf1f96471173d0fea Mon Sep 17 00:00:00 2001 From: Satyam Yadav <114805086+Coding-Professional@users.noreply.github.com> Date: Tue, 10 Nov 2026 13:38:58 +0530 Subject: [PATCH 1/2] docs: propose ADR 0002 for student portfolios Record the proposed model for student portfolios: fixed fields filled through an editor or a Markdown import, project-owned themes, shared validation rules, /u/ addresses with subdomains later, opt-in search visibility, and operator moderation. List the decisions that still need the owner's call. Link the record from the documentation index, the development guide and the architecture guide. Refs #41 --- docs/README.md | 3 +- docs/architecture.md | 4 + docs/decisions/0002-student-portfolios.md | 126 ++++++++++++++++++++++ docs/development.md | 3 +- 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 docs/decisions/0002-student-portfolios.md diff --git a/docs/README.md b/docs/README.md index 6947689..a71562b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,7 +23,8 @@ synchronization is a separate capability; paid billing is future work. ## Product decisions Architecture decisions describe a problem, the chosen boundary, and its consequences. Start with -[ADR 0001: student-product boundaries](decisions/0001-student-product-boundaries.md). Add a new +[ADR 0001: student-product boundaries](decisions/0001-student-product-boundaries.md), then +[ADR 0002: student portfolios](decisions/0002-student-portfolios.md) (proposed). Add a new decision record when a change affects persistence, account requirements, payment handling, or other feature boundaries; update the architecture guide when the implementation changes. diff --git a/docs/architecture.md b/docs/architecture.md index 5da38cd..7dcc5c0 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -139,6 +139,10 @@ CI retains failure screenshots for seven days. Backend CI restores, builds, and authentication requires no Google credentials; live OAuth and production deployment checks remain operator tasks. See [Development](development.md#checks). +Student portfolios are planned but not implemented. [ADR 0002](decisions/0002-student-portfolios.md) +records the proposed model, address scheme, and safety rules; [#40](https://github.com/procoderji-com/procoderji/issues/40) +tracks the work. + Billing, checkout, and paid entitlements are not implemented. Razorpay or Paytm is a future provider decision that also needs server-verified payment state, cancellation/support behavior, and operational readiness. Keep payment decisions outside educational scoring rules. diff --git a/docs/decisions/0002-student-portfolios.md b/docs/decisions/0002-student-portfolios.md new file mode 100644 index 0000000..9536688 --- /dev/null +++ b/docs/decisions/0002-student-portfolios.md @@ -0,0 +1,126 @@ +# ADR 0002: student portfolios + +- **Status:** Proposed; open questions below need the owner's decision before Phase 1 ships +- **Date:** 2026-11-10 +- **Tracking issue:** [#40](https://github.com/procoderji-com/procoderji/issues/40) + +## Context + +Students need a simple way to publish a portfolio: who they are, what they know, and what they +have built. Most have no hosting, domain, or time to design a page. ProCoderJii already has +optional Google accounts, an ASP.NET Core backend with EF Core persistence, and a same-origin +`/api/platform/*` layer ([ADR 0001](0001-student-product-boundaries.md)). Portfolios add the +first content that students write and the public reads, so the safety, privacy, and moderation +rules must be settled before the code. + +Two filling methods were proposed: a form, and a Markdown file the student generates with their +own AI tool. A third option, a fully editable page, was considered and rejected. + +## Decision + +### One data model, two ways to fill it + +A portfolio is a fixed set of fields: name, headline, about, skills, projects (title, link, +technologies, description), education, experience, achievements, and links (GitHub, LinkedIn, +website, email). The editor form and the Markdown import both produce this model. The Markdown +import only fills in the editor; the student reviews the result and saves. The Markdown file is +never rendered as a page. + +Students do not write HTML, CSS, JavaScript, or MDX. Pages are rendered from the model by +themes that the project owns. This keeps pages safe (no injected scripts or phishing forms), +consistent, and readable on a phone. New themes are project contributions, not student content. + +### Rules live in one place + +Field limits, link rules, username rules, reserved names, and blocked words are defined once +under `shared/portfolio/` and consumed by both runtimes, as `shared/practice/questions.json` is. +The TypeScript validator in `src/features/portfolio/` gives immediate feedback in the editor; the +.NET validator in `backend/` is the trusted check. Both run against the same fixtures. + +- Links are `https` only, plus `mailto:` for the email field. Other schemes are rejected. +- Usernames are 3 to 30 lowercase letters, digits, and single hyphens. +- Reserved names never resolve as portfolios: `www`, `api`, `app`, `admin`, `mail`, `docs`, + `blog`, `login`, `support`, `help`, `procoderji`, `satyam`, and every existing route segment + such as `u`, `learn`, `practice`, `account`, `dashboard`, `games`. +- Words that suggest phishing (for example `paytm`, `bank`, `login`, `verify`, `password`) are + blocked in usernames. + +### Address + +Phase 1 serves portfolios at `/u/` on the main site. No DNS work is needed, and the +feature can launch as soon as the pages exist. + +Phase 2 adds subdomains (`.`). A wildcard DNS record points at the frontend, +and `src/proxy.ts` rewrites the host to `/u/`. Addresses are mapped inside the +platform: no record is created per student, and students never receive DNS, hosting, or +provider credentials. One address is canonical and the other redirects to it. + +Session and antiforgery cookies stay host-only and scoped to `/api/platform`, as they are today. +A test guards against a future `Domain=.procoderji.com`, which would leak sessions to student +subdomains. + +### Ownership and state + +- One portfolio per Google account. Guests can try the editor in the browser but must sign in + to claim a username and publish. +- States: **draft** (visible only to the owner), **published** (public), **suspended** (set by + an operator; returns 404 and cannot be republished until restored). +- Search-engine visibility is opt-in. Pages are `noindex` and absent from the sitemap until the + student turns it on. +- Deleting the account deletes the portfolio. + +### Personal data + +The model has no phone number and no postal address. Email is optional and shown only if the +student fills it in. Phase 1 has no photo upload: the page shows an initials avatar. Uploads need +storage, scanning, and moderation, and are deferred until a later decision. + +### Moderation + +Every public page has a "Report this page" link that opens an email to the site contact with +the page address filled in. Operators can suspend and restore a portfolio through a documented +procedure in `backend/README.md`. Reports and suspensions are the operator's responsibility, +not an automated system. + +### Boundaries + +- `src/features/portfolio/`: types, validator, Markdown parser, editor, and theme components. + Pure rules stay independent of React, storage, and identity. +- `src/app/u/[username]/`: public page and metadata. `src/app/learn/portfolio/`: editor. +- `backend/`: `Portfolios` table, signed-in endpoints under `/api/platform/portfolio`, a public + read endpoint for published portfolios, server-side validation, rate limits, and suspension. +- `shared/portfolio/`: rules and fixtures used by both runtimes. + +### Rejected: a fully editable page + +Free-form HTML or a visual page builder would let a student publish scripts, hidden forms, or +copied designs, would break on phones, and would need a review step for every change. Students +want a good portfolio quickly, not a design tool. Themes give variety without these costs. + +## Open questions for the owner + +1. **Age requirement.** India's DPDP Act requires verifiable parental consent before processing + a child's personal data. The simplest rule is that only students aged 18 or older may publish + a public portfolio, with a confirmation step in the editor. Confirm this or choose another + rule after advice. +2. **Username changes.** Should a username be changeable after publishing? Allowing it breaks + shared links; forbidding it needs a clear notice before the first publish. +3. **Phase 2 domain.** Serve subdomains under `procoderji.com`, or buy a separate domain for + student pages (as GitHub uses `github.io`)? A separate domain protects the main site's + reputation if a page is abused. Wildcard certificates on Vercel need Vercel nameservers or + delegation of the `_acme-challenge` record. +4. **Legal text.** The Privacy and Terms pages need new sections (issue #48). The owner reviews + and approves the wording; no placeholder legal text is published. + +## Consequences + +- Students get a safe, phone-friendly portfolio in minutes without hosting knowledge. +- Themes, the Markdown template, and the parser are approachable contributions; each new theme + can be a good first issue once the theme system exists. +- The backend gains a second kind of student data with public exposure, so it also gains + moderation duties, rate limits, and new privacy and terms wording. +- Phase 2 adds DNS and certificate operations and a proxy layer; the canonical-address rule and + cookie test keep SEO and sessions correct. +- Custom domains, GitHub import, and PDF export (Phase 3) build on the same model and need no + change to these boundaries. Any paid feature still needs the payment decisions required by + ADR 0001. diff --git a/docs/development.md b/docs/development.md index d0bac1e..4649b95 100644 --- a/docs/development.md +++ b/docs/development.md @@ -108,7 +108,8 @@ by Git. [content guide](content-guide.md). Read [ADR 0001](decisions/0001-student-product-boundaries.md) before changing account, storage, -shared-data, or payment boundaries. The [architecture guide](architecture.md) describes the app. +shared-data, or payment boundaries, and [ADR 0002](decisions/0002-student-portfolios.md) before +working on student portfolios. The [architecture guide](architecture.md) describes the app. ## Checks From 9f16e1778917470f3b505e7f71daa2ddd932714f Mon Sep 17 00:00:00 2001 From: Satyam Yadav <114805086+Coding-Professional@users.noreply.github.com> Date: Tue, 10 Nov 2026 13:47:25 +0530 Subject: [PATCH 2/2] docs: address review notes on ADR 0002 Narrow the Phase 1 statement to "no DNS changes required" and point to the launch prerequisites tracked in #40. Cite the DPDP Rules, 2025 notification and distinguish the statutory timeline for Section 9 from the proposed age policy. Link Vercel's documented _acme-challenge delegation guide for the Phase 2 wildcard alternative. --- docs/decisions/0002-student-portfolios.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/decisions/0002-student-portfolios.md b/docs/decisions/0002-student-portfolios.md index 9536688..b84a0d3 100644 --- a/docs/decisions/0002-student-portfolios.md +++ b/docs/decisions/0002-student-portfolios.md @@ -47,8 +47,9 @@ The TypeScript validator in `src/features/portfolio/` gives immediate feedback i ### Address -Phase 1 serves portfolios at `/u/` on the main site. No DNS work is needed, and the -feature can launch as soon as the pages exist. +Phase 1 serves portfolios at `/u/` on the main site. Phase 1 does not require DNS +changes. Public launch still needs the backend, moderation, and owner and legal decisions tracked +in [#40](https://github.com/procoderji-com/procoderji/issues/40). Phase 2 adds subdomains (`.`). A wildcard DNS record points at the frontend, and `src/proxy.ts` rewrites the host to `/u/`. Addresses are mapped inside the @@ -99,16 +100,22 @@ want a good portfolio quickly, not a design tool. Themes give variety without th ## Open questions for the owner -1. **Age requirement.** India's DPDP Act requires verifiable parental consent before processing - a child's personal data. The simplest rule is that only students aged 18 or older may publish - a public portfolio, with a confirmation step in the editor. Confirm this or choose another - rule after advice. +1. **Age requirement.** Section 9 of India's Digital Personal Data Protection Act, 2023 will + require verifiable parental consent before processing a child's personal data. The DPDP + Rules, 2025 were notified on 13 November 2025 (MeitY, G.S.R. 843(E)), and Section 9 is + scheduled to commence 18 months after that date, so it is not yet in force on this ADR's + date. Separately from the statutory timeline, the proposed product policy is that only + students aged 18 or older may publish a public portfolio, with a confirmation step in the + editor. Confirm this policy, or choose another rule after legal advice. 2. **Username changes.** Should a username be changeable after publishing? Allowing it breaks shared links; forbidding it needs a clear notice before the first publish. 3. **Phase 2 domain.** Serve subdomains under `procoderji.com`, or buy a separate domain for student pages (as GitHub uses `github.io`)? A separate domain protects the main site's - reputation if a page is abused. Wildcard certificates on Vercel need Vercel nameservers or - delegation of the `_acme-challenge` record. + reputation if a page is abused. Wildcard certificates on Vercel need + [Vercel nameservers](https://vercel.com/guides/why-use-domain-nameservers-method-wildcard-domains), + or the documented alternative of delegating the `_acme-challenge` record to Vercel DNS with + `NS` records while keeping the current nameservers + ([Vercel guide](https://vercel.com/kb/guide/wildcard-domain-without-vercel-nameservers)). 4. **Legal text.** The Privacy and Terms pages need new sections (issue #48). The owner reviews and approves the wording; no placeholder legal text is published.