Technology deserves a second life. So does the right to use it.
RevampIT is a Swiss nonprofit enabling the free exchange of technology on a nonprofit basis. We redistribute computers, hardware, and software while promoting open-source as the ideal form of human collaboration. Based in Zurich, everything we build serves that mission -- including this codebase.
We built a lightweight CMS instead of adopting Strapi. The reasoning:
- Complete control over features and TypeScript integration -- no fighting the framework
- Lighter footprint -- simpler deployment, lower resource usage
- No complexity tax -- Strapi's setup conflicts and over-engineering weren't worth it
The CMS runs as an Express.js backend (port 3001) with JWT authentication, role-based access control (Admin / Editor / Viewer), and a RESTful API.
src/config/database.ts defines 165 table name constants. Every database query references TABLE_NAMES -- never a hardcoded string. The constants are organized into logical groups:
User & Auth | Inventory | Messaging | Services | Workshops | Locations
Applications | Payments | Reviews | Documents | IT-Hilfe | HIRN AI
Staff | Tasks | Content | Activity Stream | Meeting Protocols
P2P Marketplace | Organizational Numbers
Related SSOT exports live alongside: APPOINTMENT_ROLES, REVIEW_TARGET_TYPES, CONVERSATION_TYPES, SERVICE_CATEGORIES, FEATURED_SERVICE_SLUGS.
Adding a new domain means adding constants to one file. If a table name is wrong, it's wrong in one place.
Three tiers, zero ambiguity:
Users --> Staff (@revamp-it.ch email) --> Super Admins (hardcoded list)
is_staffboolean +staff_permissionstext array on the users table- Staff detection by email domain; super admins by explicit list
- Sensitive sections require permission checks -- no implicit trust
draft --> pending --> approved / rejected
Stored in user_content_submissions. Nothing goes live without review.
In-house AI knowledge management system with an action cockpit and executor. Handles organizational intelligence -- not a chatbot wrapper.
These are enforced, not suggested:
- Logger --
import { logger } from '@/lib/logger'. Neverconsole.log. - TABLE_NAMES -- never hardcoded table strings. Import from
src/config/database.ts. - Parameterized queries -- never string concatenation. No exceptions.
- Swiss German -- user-facing text uses
ss(notß), properä/ö/ü(neverae/oe/ue).npm run lint:umlautscatches violations.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 18, TypeScript 5, Tailwind 3 |
| CMS | Express.js, JWT, RBAC |
| Database | PostgreSQL (Neon), Redis, Meilisearch |
| Payments | Stripe |
| Nodemailer (Listmonk / Brevo) | |
| AI | HIRN (in-house), OpenAI |
| Maps | Leaflet |
| Testing | Jest (312 tests), Playwright (E2E) |
| CI/CD | GitHub Actions, Vercel |
Quick Start
- Node.js 20+
- PostgreSQL (or a Neon account)
- Redis
git clone https://github.com/revamp-it/revampit.git
cd revampit
cp .env.example .env.local # fill in your database URL, Stripe keys, etc.
npm install
npm run db:migrate
npm run dev # Next.js on :3000, CMS on :3001At minimum, configure:
DATABASE_URL-- PostgreSQL connection stringREDIS_URL-- Redis connection stringSTRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRETJWT_SECRET
See .env.example for the full list.
312 tests across 24 suites.
| Category | Coverage |
|---|---|
| API routes | Notifications, admin, IT-Hilfe |
| Business logic | Protocols, payments, currency, tax compliance, HIRN AI |
| Auth | Password handling, permissions, rate limiter |
| Data processing | Bulk extraction, file parsing, CSV export/import |
| Validation | Schema tests |
| E2E (Playwright) | Auth smoke, marketplace, IT-Hilfe, security |
npm test # run all Jest tests
npm run test:e2e # run Playwright E2E suiteDefined in .github/workflows/ci.yml:
- Code Quality -- ESLint + TypeScript type check + Next.js build
- Auth Smoke Test -- Playwright, runs conditionally
- Unit Tests -- Jest, PR only
Vercel handles production deployment on merge to main.
src/
app/ # Next.js pages and API routes
components/ # React components (UI only, no business logic)
config/
database.ts # TABLE_NAMES SSOT (165 constants)
lib/
auth/ # JWT, permissions, staff detection
domain/ # Business logic (no HTTP, no UI)
email/ # Templates and delivery
logger.ts # Structured logging
hooks/ # Data fetching, state management
scripts/
db/migrations/ # Sequential SQL migrations
tests/ # Jest test suites
e2e/ # Playwright E2E tests
cms/ # Express.js CMS backend
- Fork and create a feature branch
- Follow the development standards (TABLE_NAMES, logger, parameterized queries, Swiss German rules)
- Run
npm testandnpm run lint:umlautsbefore pushing - Open a PR against
main-- CI will validate code quality and tests
MIT
Revamp-IT -- Birmensdorferstrasse 379, 8055 Zürich -- revamp-it.ch