Fujimod
Try your camera firmware in the browser and build Fujimod SD boot files.
Concerts, comedy, workshops, sports and festivals — plus bands, DJs and performers for your own wedding, party or corporate event. No account needed to browse.
LifestyleGitHub @curatixliveOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A production-track event ticketing & experience platform (Eventbrite/Meetup
class): organizers create events and ticket tiers, attendees book and pay,
the platform takes a fee per ticket and splits the rest to the organizer,
tickets get checked in at the door. This repo contains the foundation plus
the complete backend feature set — nine modules (accounts,
organizations, events, ticketing, booking, payments, checkin,
notifications, settlements) proving the whole stack works end to end:
architecture, caching, full-text search, correct-under-concurrency
reservations, the reserve→hold→confirm→pay money-path lifecycle with
signature-verified webhooks and automatic refunds, one-scan gate entry that
can't admit a ticket twice, event-driven exactly-once email/SMS delivery, and
organizer payouts that close the money loop (reconciled, released once, only
after the event) — with performance discipline throughout.
frontend/README.md); comes after more backend modules exist.cp .env.example .env # already has safe dummy values, edit if you like
docker compose up -d
This builds the backend image and starts Postgres, a PgBouncer in front of
it (transaction-pooling mode, TLS required — a local stand-in for
Supabase's Supavisor pooler), Redis with a TLS listener (a local stand-in for
Upstash), waits for them to be healthy, runs migrations, and starts the
dev server on http://localhost:8000.
Development lives in docker-compose.override.yml, which Compose loads
automatically — so the command above is development, and
docker compose -f docker-compose.yml up -d # production: .env is authoritative
is production (gunicorn, plus the scheduler and outbox worker; no migrate on boot).
Deployment is a configuration exercise, not a development exercise — the
same image runs all three environments and only .env differs:
| Document | Answers |
|---|---|
| DEPLOYMENT.md | How do I deploy it, and how do I undo it? |
| PRODUCTION_CHECKLIST.md | Tickable sign-off sheet before go-live. |
| OPERATIONS.md | It is deployed — how do I run it day to day? |
| ENVIRONMENT_VARIABLES.md | What is every variable, and who reads it? |
| REAL_INTEGRATIONS_AUDIT.md | What is each credential and where do I get it? |
Environment templates — copy the one for your target to .env, fill in every
<PLACEHOLDER>, and change nothing else:
| Template | For |
|---|---|
.env.example | Local development, and the canonical reference for every variable. |
.env.staging.example | Staging. |
.env.production.example | Production. |
frontend/.env.local.example · frontend/.env.production.example | The frontend's seven public variables. |
All four backend templates declare the identical variable set, enforced by
core/tests/test_env_templates.py rather than by asking.
GET /health/GET /api/schema/ — Swagger UI: /api/docs/POST /api/v1/auth/register, /login, /refresh,
/logout, GET /api/v1/auth/mePOST /api/v1/organizations/, GET /api/v1/organizations/{id},
PATCH /api/v1/organizations/{id}, GET /api/v1/organizations/ (mine,
cursor-paginated), POST /api/v1/organizations/{id}/verification,
POST /api/v1/organizations/{id}/payout-accountGET /api/v1/events (browse + full-text search ?q= + ?city= filter,
cursor-paginated), GET /api/v1/events/{id}. Organizer (authenticated):
POST /api/v1/events (draft), PATCH /api/v1/events/{id} (optimistic-
locked), POST /api/v1/events/{id}/publish, GET /api/v1/organizer/events.GET /api/v1/events/{id}/ticket-types
(tiers + live availability, short-TTL cached). Organizer:
POST /api/v1/events/{id}/ticket-types, PATCH /api/v1/ticket-types/{id}.
The reserve/release/confirm_sold primitives (per-tier row lock, zero
oversell) are an internal service API booking calls — not HTTP.POST /api/v1/bookings (reserve all items
all-or-nothing, hold, create payment order; honours an Idempotency-Key
header), GET /api/v1/bookings/{id}, POST /api/v1/bookings/{id}/cancel,
GET /api/v1/me/tickets. ConfirmBooking (issue signed-QR tickets,
idempotent) is an internal service API payments calls from the verified
webhook. A sweeper task auto-releases expired holds.POST /api/v1/payments/webhook (Razorpay only — no user
token, authenticated by HMAC signature over the raw body; verifies →
dedupes → amount-checks → confirms the booking → 200 fast, refunds
offloaded), GET /api/v1/payments/{id} (owner/organizer),
POST /api/v1/payments/{id}/refund (organizer/admin). The order carries a
Route split (organizer share on-hold until the event; platform fee retained);
hold-expired/amount-mismatch payments auto-refund — money is never kept
without a ticket.cd backend
python -m venv .venv
./.venv/Scripts/python -m pip install -e ".[dev]" # Windows
# source .venv/bin/activate && pip install -e ".[dev]" # macOS/Linux
docker compose up -d postgres redis # from repo root, in another shell
python manage.py migrate
python manage.py runserver
Everything runs with zero real credentials — every third-party
dependency (payments, storage, email, SMS, event bus, task queue) defaults
to a local/fake adapter (see .env.example's *_BACKEND/*_PROVIDER
switches). Nothing needs a Razorpay key, a GCP project, or an SMTP server
to run locally.
cd backend
./.venv/Scripts/python -m pytest --cov=core --cov=apps --cov-report=term-missing
./.venv/Scripts/python -m ruff check .
./.venv/Scripts/python -m black --check .
./.venv/Scripts/python -m mypy .
Tests need Postgres + Redis running (docker compose up -d postgres redis
from the repo root; add pgbouncer too if you want the pooled path
exercised, though tests connect directly via DIRECT_DATABASE_URL and
don't need it) — pytest-django creates and tears down its own test database
against Postgres directly, bypassing the pooler (see CLAUDE.md's dev
infrastructure section for why). One test suite (test_redis_adapter.py)
talks to real Redis to verify cache serialization; everything else uses
the local/fake adapters.
Want a deep per-request profiler instead of the built-in slow-request log?
Set ENABLE_SILK=true in .env and hit /silk/ — off by default even in
dev, since it has real overhead.
Install the git hooks once so these run automatically before every commit:
pip install pre-commit # or use the one in backend/.venv
pre-commit install
See CLAUDE.md for the full conventions doc (layering rules, how to add a module, how to add a port/adapter, why certain things are deliberately kept simple). Short version:
API (views/serializers, thin) -> Service (business rules) -> Repository (ORM) -> Models
Every third-party dependency sits behind a port (an abstract interface
in backend/core/ports/), with a local/fake adapter for dev/test and a
real adapter for production, selected at runtime by backend/config/di.py
(the single composition root) based on env-var switches. Business logic
never imports a vendor SDK directly.
backend/
config/ settings (base/dev/staging/prod/test), di.py, urls, asgi/wsgi, worker
core/ shared kernel: ports, adapters (local + real), base repo/service,
unit of work, outbox, audit, errors, pagination, logging
apps/
accounts/ reference module — copy this shape for every new module
organizations/ orgs/brands, verification, payout-account linking, caching
events/ public discovery: full-text search, edge caching,
single-flight detail cache, optimistic-locked edits
ticketing/ tiers + authoritative availability; per-tier row-lock
reserve/release/confirm primitives (zero oversell)
booking/ reserve→hold→confirm money-path lifecycle; all-or-nothing
reserve, auto-release sweeper, signed-QR ticket issuance
payments/ signature-verified Razorpay webhooks, idempotency ledger,
Route split (on-hold), auto-refunds when unfulfillable
checkin/ one-scan gate entry under a per-ticket row lock, live
attendance (cache the count, trust the DB), scan audit log
notifications/ event-driven email/SMS: exactly-once (unique dedupe_key +
claim-before-send), retry + dead-letter, templated + DLT
settlements/ closes the money loop: reconcile gross/fee/refunds/net from
payment records, release organizer payout once after the
event (recompute under lock, retry + dead-letter)
frontend/ placeholder, see frontend/README.md
private, no-storePOST /api/v1/checkin/verifyGET /api/v1/events/{id}/attendanceUSER_REGISTERED, BOOKING_CONFIRMED,
PAYMENT_REFUNDED, EVENT_PUBLISHED, PAYOUT_RELEASED) and sends templated
email/SMS through EmailPort/SmsPort. Delivery is fully async (off the
request path via the task queue), exactly-once (a unique dedupe_key +
claim-before-send row lock), with retry → dead-letter. The ticket-delivery
email (event + booking reference + QR) and OTP SMS (India DLT template per
type) live here; the welcome email was consolidated in from accounts.private, no-store): GET /api/v1/organizer/settlements
(own settlements, cursor-paginated), GET /api/v1/organizer/settlements/{event_id},
POST /api/v1/admin/settlements/{id}/release (staff-only manual trigger).
Closes the money loop: it reconciles each event's gross − fee − refunds = net from the payment records and releases the on-hold organizer payout —
recomputed authoritatively under a row lock, exactly once, and only
after the event + refund window — with retry → dead-letter (the payout runs
off the request path via a scheduled job).