System for Tracking and Organization of Containers and Kartons
MUNify STOCK is inventory management software for Model United Nations conferences, part of the MUNify ecosystem by Deutsche Model United Nations (DMUN) e.V.
- Inventory Management — Track items, containers, and locations with full CRUD
- QR Code / Barcode Scanning — Scan and generate QR codes for items and containers
- Flag Management — Dedicated country flag inventory with checklist workflow
- General Inventory Sessions — Container-based inventory with conflict detection
- Audit Trail — Full change history per entity, browsable in the UI
- Global Search — Fuzzy search across items, containers, and flags (Cmd+K)
- i18n — German and English via Paraglide
- DMUN Corporate Identity — Shared theme with light/dark mode
- Frontend: SvelteKit 2, Svelte 5 (runes), Tailwind CSS 4, DaisyUI 5
- Backend: GraphQL via rumble (Pothos + GraphQL Yoga)
- Database: PostgreSQL via Drizzle ORM
- Auth: OIDC via
@logto/sveltekit(Logto) + M2M bearer token support - GraphQL Client: rumble's built-in client generator (URQL-based)
# 1. Install dependencies
bun install
# 2. Set up environment variables
cp .env.example .env
# Edit .env with your Logto credentials and database URL
# 3. Generate local HTTPS certificates (required)
mkcert -install
mkdir -p .certs
mkcert -key-file .certs/key.pem -cert-file .certs/cert.pem localhost 127.0.0.1 ::1
# 4. Start PostgreSQL, then dev server
bun run dev
# 5. Push database schema
bun run db:push
# 6. Generate the GraphQL client (dev server must be running)
bun run generate:clientThe app will be available at https://localhost:5173. You'll need a Logto instance configured (see .env.example).
Why HTTPS in dev? The app uses Server-Sent Events (SSE) for live GraphQL subscriptions, with each subscription holding an open HTTP connection. Browsers limit concurrent connections to ~6 per origin on HTTP/1.1, which the app easily exceeds. HTTPS enables HTTP/2, which multiplexes all requests over a single connection and eliminates this limit.
| Command | Description |
|---|---|
bun run dev |
Start Docker + dev server |
bun run dev:server |
Dev server only (no Docker) |
bun run build |
Production build |
bun run check |
Svelte + TypeScript type checking |
bun run lint |
Prettier + ESLint check |
bun run format |
Auto-format all files |
bun run generate:client |
Generate typed GraphQL client (requires running dev server) |
bun run db:push |
Push Drizzle schema to database |
bun run db:migrate |
Run Drizzle migrations |
bun run db:studio |
Open Drizzle Studio (DB GUI) |
See .env.example for all required variables. Key ones:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
PUBLIC_LOGTO_ENDPOINT |
Logto instance URL |
PUBLIC_LOGTO_APP_ID |
Logto application ID |
LOGTO_APP_SECRET |
Logto application secret |
LOGTO_COOKIE_ENCRYPTION_KEY |
Random string for session cookie encryption |
LOGTO_ROLE_CLAIM |
JWT claim name for roles |
LOGTO_API_RESOURCE |
API resource identifier for M2M token validation |
ACCESS_DOMAIN_WHITELIST |
Comma-separated email domains for app access |
Bulk-import items, containers, locations, and container types from a CSV file. The CSV is expected to have the following columns (in order):
| Column | Header | Description |
|---|---|---|
| 0 | Nummer | Custom ID for the item |
| 1 | Artikel | Item name |
| 2 | Anzahl | Quantity (number or free-text description) |
| 3 | Verpackung | Container name (e.g. "Kiste 11") or "lose" |
| 4 | Kistenbezeichnung | Container label |
| 5 | Standort | Location name (e.g. "Kiel") |
| 6 | Anmerkung | Notes / description |
| 7 | Alternative Schlagworte | Comma-separated aliases |
Send a POST request to /api/csv-import. Requires admin authentication (session or M2M bearer token with admin / stock:admin role).
# Multipart form upload
curl -X POST https://localhost:5173/api/csv-import \
-H "Authorization: Bearer <token>" \
-F file=@inventory.csv
# Raw CSV body
curl -X POST https://localhost:5173/api/csv-import \
-H "Authorization: Bearer <token>" \
-H "Content-Type: text/csv" \
--data-binary @inventory.csvThe endpoint returns a JSON summary:
{
"locationsCreated": 3,
"containerTypesCreated": 5,
"containersCreated": 24,
"itemsCreated": 142,
"itemsFailed": 0,
"rowsSkipped": 7,
"errors": []
}bun run scripts/import-inventory.ts <path-to-csv>Set DATABASE_URL to override the default PostgreSQL connection (postgres://postgres:postgres@localhost:5432/postgres).
Can I use this for my conference outside of DMUN?
Yes. We encourage and allow usage for other conferences. Please see our license for more detailed information. Note that the project is still under development. If you are interested in using it, please contact us via the discussion section of this repository.
See CONTRIBUTING.md for guidelines on commits, branches, and pull requests.
This aspect is work in progress since the project is currently in its development phase. See LICENSE.
You can support our work by donating to DMUN e.V.. Contact vorstand@dmun.de for details.