Skip to content

Commit be37e8f

Browse files
docs: make the repo discoverable and contributor-ready
Rewrite the README opener with badges, a live-instance link and a feature table, and add the community health files GitHub looks for: CONTRIBUTING (setup, branch/commit conventions, the five things reviewers actually check), SECURITY (private reporting, in/out of scope for a multi-tenant app), CODE_OF_CONDUCT, issue forms and a PR template. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01APEKg6qy9TcLausNecrg89
1 parent 0687232 commit be37e8f

8 files changed

Lines changed: 310 additions & 3 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Bug report
2+
description: Something is broken
3+
labels: [bug]
4+
body:
5+
- type: textarea
6+
id: what
7+
attributes:
8+
label: What happened
9+
description: What you expected, and what happened instead.
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: steps
14+
attributes:
15+
label: Steps to reproduce
16+
placeholder: |
17+
1. Log in as owner@e2etest.com on lvh.me:3000
18+
2. Go to /dashboard/admin/...
19+
3. ...
20+
validations:
21+
required: true
22+
- type: dropdown
23+
id: role
24+
attributes:
25+
label: Role you were signed in as
26+
options: [student, teacher, admin, super admin, not signed in]
27+
validations:
28+
required: true
29+
- type: input
30+
id: tenant
31+
attributes:
32+
label: Tenant / URL
33+
description: Which subdomain, and the page URL.
34+
placeholder: code-academy.lvh.me:3000/en/dashboard/student
35+
- type: dropdown
36+
id: env
37+
attributes:
38+
label: Environment
39+
options: [local dev, self-hosted, hosted instance]
40+
validations:
41+
required: true
42+
- type: textarea
43+
id: logs
44+
attributes:
45+
label: Console / server errors
46+
description: Browser console, terminal output, or Supabase logs. Screenshots welcome.
47+
render: shell

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Question or idea
4+
url: https://github.com/guillermoscript/lms-front/discussions
5+
about: Setup help, architecture questions, and open-ended ideas go in Discussions.
6+
- name: Report a vulnerability
7+
url: https://github.com/guillermoscript/lms-front/security/advisories/new
8+
about: Please report security issues privately, not as a public issue.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Feature request
2+
description: Propose something new
3+
labels: [enhancement]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: Problem
9+
description: What can't you do today? Who is blocked — a student, a teacher, a school admin, a self-hoster?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: proposal
14+
attributes:
15+
label: Proposed solution
16+
validations:
17+
required: true
18+
- type: dropdown
19+
id: area
20+
attributes:
21+
label: Area
22+
options:
23+
- courses / lessons
24+
- exams / grading
25+
- payments / billing
26+
- multi-tenancy / onboarding
27+
- gamification
28+
- AI tutor / MCP server
29+
- community spaces
30+
- i18n / translations
31+
- admin dashboard
32+
- other
33+
- type: checkboxes
34+
id: help
35+
attributes:
36+
label: Contribution
37+
options:
38+
- label: I'd be willing to work on this

.github/pull_request_template.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## What
2+
3+
<!-- What changed, in one or two sentences. -->
4+
5+
Closes #
6+
7+
## Why
8+
9+
<!-- The problem this solves. Link the issue if there is one. -->
10+
11+
## How to QA
12+
13+
<!-- Steps a reviewer can follow on a fresh `npm run db:reset`. Include the account and subdomain. -->
14+
15+
1.
16+
2.
17+
18+
## Screenshots / GIF
19+
20+
<!-- Required for anything a user can see or click. Before + after if it's a change. -->
21+
22+
## Checklist
23+
24+
- [ ] `npm run typecheck` and `npm run test:unit` pass
25+
- [ ] `npm run build` passes
26+
- [ ] Every new tenant-scoped query filters by `tenant_id` (or the table genuinely has no such column)
27+
- [ ] Tested with every relevant role (student / teacher / admin)
28+
- [ ] Loading and error states handled
29+
- [ ] New UI strings added to both `messages/en.json` and `messages/es.json`
30+
- [ ] Migration (if any) applies cleanly on `npm run db:reset`, has RLS policies, and `lib/database.types.ts` was regenerated

CODE_OF_CONDUCT.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Code of Conduct
2+
3+
## Our pledge
4+
5+
We want this project to be a place where anyone can ask a question, report a bug, or send a patch
6+
without fear of being belittled for it. Everyone who takes part — contributors, maintainers, and
7+
people just passing through an issue thread — is expected to help keep it that way.
8+
9+
## Expected behavior
10+
11+
- Be respectful and assume good faith. People come from different backgrounds and skill levels, and
12+
the project spans two languages (English and Spanish) — both are welcome in issues and PRs.
13+
- Give and take feedback on the work, not the person.
14+
- Keep discussion focused on the project.
15+
16+
## Unacceptable behavior
17+
18+
- Harassment, insults, or personal attacks
19+
- Discriminatory language or imagery, sexual attention or advances
20+
- Publishing someone's private information without permission
21+
- Sustained disruption of discussions
22+
23+
## Enforcement
24+
25+
Maintainers may remove comments, close issues or PRs, and block accounts that violate this policy.
26+
27+
Report problems to **arepayquezo@gmail.com**. Reports stay confidential; the reporter's identity is
28+
not shared with the person reported. Maintainers who do not uphold this policy in good faith may
29+
face consequences decided by the other maintainers.
30+
31+
## Scope
32+
33+
This applies in all project spaces — issues, pull requests, discussions, commit messages — and when
34+
representing the project in public.
35+
36+
Adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.

CONTRIBUTING.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Contributing
2+
3+
Thanks for considering a contribution. This is a real, running product, so the bar is "it works for every tenant and every role" — but the setup is a single `npm install` + `supabase start` away, and small fixes are very welcome.
4+
5+
## Ways to help
6+
7+
- **Good first issues**[`good first issue`](https://github.com/guillermoscript/lms-front/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and [`help wanted`](https://github.com/guillermoscript/lms-front/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
8+
- **Bugs** — open an issue with the tenant, role, and steps to reproduce
9+
- **Translations**`messages/en.json` and `messages/es.json`; new locales welcome
10+
- **Docs** — anything in `docs/` that was wrong or missing when you set up
11+
- **Payment providers** — the provider contract lives in `lib/payments/` (see `docs/PROVIDER_AGNOSTIC_PAYMENTS_SPIKE.md`)
12+
13+
## Setup
14+
15+
Full walkthrough: [`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md). The short version:
16+
17+
```bash
18+
npm install
19+
cp .env.example .env.local # fill in the four local Supabase vars
20+
supabase start && npm run db:reset
21+
npm run dev # open http://lvh.me:3000 — NOT localhost
22+
```
23+
24+
Seeded logins (all `password123`, local dev only) are listed in the [README](README.md#quick-start).
25+
26+
## Workflow
27+
28+
1. Branch from `master`: `<type>/<slug>-<issueNumber>` — e.g. `fix/payout-rounding-516`
29+
2. Commit with [Conventional Commits](https://www.conventionalcommits.org/): `fix(payments): ...`, `feat(admin): ...`, `docs: ...`
30+
3. Open a PR against `master`, filling in the template (what changed, why, how to QA)
31+
4. CI runs typecheck + unit tests on every PR; lint is surfaced but non-blocking (there is a large pre-existing baseline — just keep the files *you* touch clean)
32+
33+
Before pushing:
34+
35+
```bash
36+
npm run typecheck
37+
npm run test:unit
38+
npm run build # catches what typecheck alone misses
39+
npx playwright test # if you touched auth, tenancy, or payments
40+
```
41+
42+
## What reviewers look for
43+
44+
This is a **multi-tenant** app with **RLS as the security boundary**. Most review comments come from these five:
45+
46+
- **Every tenant-scoped query filters by `tenant_id`** — even though RLS also enforces it. Exceptions: `profiles`, `gamification_levels`, `lesson_completions`, and the exam child tables, which have no `tenant_id` column at all.
47+
- **Reads go straight from components via RLS.** Server actions are for multi-step mutations, service-role work, and external APIs (Stripe, email) — not for ordinary reads.
48+
- **`createAdminClient()` bypasses RLS.** If you use it, validate tenant ownership by hand before any write.
49+
- **Tested with every relevant role** — student, teacher, admin — and on both seeded tenants.
50+
- **Loading and error states handled**, and any new UI string added to both `en.json` and `es.json`.
51+
52+
Architecture, schema invariants, and the list of known pitfalls live in [`CLAUDE.md`](CLAUDE.md) — it is written for AI agents but it is the fastest orientation for humans too. Schema details: [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md).
53+
54+
## Database changes
55+
56+
```bash
57+
supabase migration new <name> # never edit an applied migration
58+
npm run db:reset # verify it applies from scratch, with the seed
59+
npm run db:types # regenerate lib/database.types.ts, commit the diff
60+
```
61+
62+
New tenant-scoped table? It needs `tenant_id`, RLS enabled, and policies — a table without policies is invisible to the app and a table without `tenant_id` leaks across schools.
63+
64+
## Security
65+
66+
Do not open a public issue for a vulnerability. See [SECURITY.md](SECURITY.md).
67+
68+
## Questions
69+
70+
Open a [Discussion](https://github.com/guillermoscript/lms-front/discussions) or comment on the issue you want to pick up.

README.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
# LMS Platform
22

3-
A multi-tenant SaaS Learning Management System. Schools run on subdomains (`school.platform.com`). Educators create and sell courses; students enroll and learn.
3+
**Open-source, multi-tenant LMS for creators and schools.** Every school gets its own subdomain (`school.platform.com`), its own branding, and its own students. Educators build courses and sell them; students enroll, learn, take exams, and earn verifiable certificates.
44

5-
**Stack:** Next.js 16 · React 19 · TypeScript · Supabase · Shadcn UI · Tailwind CSS v4 · Stripe Connect · next-intl (en/es)
5+
[![CI](https://github.com/guillermoscript/lms-front/actions/workflows/ci.yml/badge.svg)](https://github.com/guillermoscript/lms-front/actions/workflows/ci.yml)
6+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7+
[![Next.js 16](https://img.shields.io/badge/Next.js-16-black?logo=next.js)](https://nextjs.org)
8+
[![Supabase](https://img.shields.io/badge/Supabase-Postgres%20%2B%20RLS-3ECF8E?logo=supabase&logoColor=white)](https://supabase.com)
9+
[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
10+
11+
**Live instance:** [preciopana.com](https://preciopana.com) · **Setup:** [`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md) · **Contribute:** [`CONTRIBUTING.md`](CONTRIBUTING.md)
12+
13+
**Stack:** Next.js 16 · React 19 · TypeScript · Supabase (Postgres + Auth + RLS) · Shadcn UI (base-mira) · Tailwind CSS v4 · Stripe Connect · next-intl (en/es)
14+
15+
## What's in it
16+
17+
| | |
18+
|--|--|
19+
| **Multi-tenancy** | Subdomain-per-school, tenant theming, per-tenant roles — one deployment, many schools. Isolation is enforced in Postgres with Row Level Security, not in application code. |
20+
| **Courses** | Block-editor lessons with rich MDX components, exercises, checkpoints, exams with AI-assisted grading, progress tracking, FSRS spaced repetition. |
21+
| **Payments** | Stripe Connect (platform fee + revenue split), PayPal, Lemon Squeezy, Solana, Binance, and manual/offline receipts for markets where cards fail. Provider-agnostic contract — adding one is a single module. |
22+
| **Monetization** | One-off products, subscriptions, plan-based feature gating, payouts, invoices, revenue dashboard. Separate platform billing for schools paying you. |
23+
| **AI tutor** | An MCP server (`mcp-server/`) exposing the LMS as tools + interactive widgets: drill practice, weak-topic remediation, exam readiness, ask-a-teacher. Works from any MCP client, auth'd via Supabase OAuth 2.1 with RLS intact. |
24+
| **Engagement** | XP, levels, streaks, achievements, challenges, weekly leagues, coin store, certificates with public verification, community spaces with polls and moderation. |
25+
| **Creator tools** | AI landing-page generation, drag-and-drop page builder, guided onboarding, guided tours. |
26+
| **i18n** | Full English + Spanish across the app, built for LATAM and English-speaking markets. |
27+
28+
Self-host it, fork it for your own school, or use it as a reference for multi-tenant Supabase + Next.js patterns. MIT licensed.
629

730
## Prerequisites
831

@@ -15,7 +38,7 @@ A multi-tenant SaaS Learning Management System. Schools run on subdomains (`scho
1538

1639
1. **Clone and install**
1740
```bash
18-
git clone <repo-url>
41+
git clone https://github.com/guillermoscript/lms-front.git
1942
cd lms-front
2043
npm install
2144
```
@@ -85,3 +108,20 @@ A multi-tenant SaaS Learning Management System. Schools run on subdomains (`scho
85108
- [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md) — complete DB schema
86109
- [`docs/AUTH.md`](docs/AUTH.md) — authentication flows
87110
- [`docs/MONETIZATION.md`](docs/MONETIZATION.md) — billing and payments
111+
- [`docs/MCP_SETUP.md`](docs/MCP_SETUP.md) — the MCP server and AI tutor tooling
112+
113+
More in [`docs/`](docs/) — deployment, i18n, gamification, community spaces, the landing-page builder.
114+
115+
## Contributing
116+
117+
Contributions are welcome — bug reports, translations, docs fixes, new payment providers, features.
118+
119+
- Read [`CONTRIBUTING.md`](CONTRIBUTING.md) for the workflow and what reviewers look for
120+
- Browse [`good first issue`](https://github.com/guillermoscript/lms-front/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and [`help wanted`](https://github.com/guillermoscript/lms-front/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
121+
- Questions and ideas: [Discussions](https://github.com/guillermoscript/lms-front/discussions)
122+
- Found a vulnerability? [`SECURITY.md`](SECURITY.md) — please report it privately
123+
- By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md)
124+
125+
## License
126+
127+
[MIT](LICENSE) — free to self-host, fork, and build a business on.

SECURITY.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Security Policy
2+
3+
## Reporting a vulnerability
4+
5+
**Please do not open a public issue.** Report privately via
6+
[GitHub Security Advisories](https://github.com/guillermoscript/lms-front/security/advisories/new),
7+
or email **arepayquezo@gmail.com** with `[security]` in the subject.
8+
9+
Include: what you found, how to reproduce it, and the impact you think it has. A proof of concept
10+
against your own local instance is ideal.
11+
12+
Expect an acknowledgement within a few days. Please give a reasonable window for a fix before
13+
disclosing publicly.
14+
15+
## In scope
16+
17+
This is a multi-tenant platform, so anything that crosses a boundary is high priority:
18+
19+
- **Cross-tenant data access** — reading or writing another school's data
20+
- **Privilege escalation** — student → teacher/admin, tenant admin → super admin
21+
- **RLS bypass** — reaching rows a policy should have blocked
22+
- **Payment integrity** — gaining course access without a successful transaction or valid entitlement, tampering with revenue splits or payouts
23+
- **Auth flaws** — session fixation, JWT claim forgery, broken password reset
24+
- **Exposure of secrets** — service-role keys or provider credentials leaking to the browser bundle
25+
26+
## Out of scope
27+
28+
- The seeded local-dev accounts and their `password123` passwords (`supabase/seed.sql`) — local only, never deployed
29+
- The hardcoded Sentry DSN in `sentry.server.config.ts` — public by design
30+
- `NEXT_PUBLIC_*` values being visible in the client bundle — that is what the prefix means
31+
- Findings that require a self-hosted operator to misconfigure their own instance
32+
- Automated scanner output with no demonstrated impact, missing security headers with no exploit path, DoS by volume
33+
34+
## Self-hosting notes
35+
36+
If you run your own instance: keep `SUPABASE_SERVICE_ROLE_KEY` server-side only, never put a
37+
production OpenAI key in `NEXT_PUBLIC_OPENAI_API_KEY` (it ships to the browser), reseed nothing
38+
from `supabase/seed.sql` in production, and verify RLS is enabled on every table you add.

0 commit comments

Comments
 (0)