diff --git a/CLAUDE.md b/CLAUDE.md index 65e1f3eb9..79cf8deaa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,7 +31,7 @@ Internal identifiers (Go module `schej.it/server`, Mongo DB `schej-it`, prod ema - MongoDB backup/restore: `mongodump --host=localhost:27017 --db=schej-it` / `mongorestore --uri mongodb://localhost:27017 ./dump --drop`. ### Required env vars for local server boot -`SESSION_SECRET` (≥32 chars) is enforced at startup. `CLIENT_ID`/`CLIENT_SECRET` (Google OAuth) and `ENCRYPTION_KEY` are required for most flows. See `server/.env.template` and `DEPLOYMENT.md` for the full list (Stripe, Microsoft, Listmonk, Slack, Discord, Gmail, etc.). +`SESSION_SECRET` (≥32 chars) is enforced at startup. `CLIENT_ID`/`CLIENT_SECRET` (Google OAuth) and `ENCRYPTION_KEY` are required for most flows. See `server/.env.template` and `DEPLOYMENT.md` for the full list (Microsoft, Listmonk, Slack, Discord, Gmail, etc.). For local frontend → local backend, set `CORS_ORIGINS=http://localhost:8080` in `server/.env`. @@ -40,7 +40,7 @@ For local frontend → local backend, set `CORS_ORIGINS=http://localhost:8080` i ### Backend (Gin + MongoDB) `server/main.go` wires everything: CORS, cookie sessions, Mongo init (`db.Init`), Google Cloud Tasks init (`services/gcloud.InitTasks`), then mounts API groups under `/api` via `routes.Init*` and `slackbot.InitSlackbot`. After API routes, it walks `frontend/dist` and registers each file as a static route, loads `index.html` as a template, and falls back to a `NoRoute` handler that injects per-route OG meta tags (e.g. for `/e/:eventId` it looks up the event to set the title and OG image). -- `routes/` — HTTP handlers grouped by domain: `auth.go`, `user.go`, `users.go`, `events.go`, `folders.go`, `analytics.go`, `stripe.go`. Route comments use Swag annotations; `swag init` regenerates `docs/`. +- `routes/` — HTTP handlers grouped by domain: `auth.go`, `user.go`, `users.go`, `events.go`, `folders.go`, `analytics.go`. Route comments use Swag annotations; `swag init` regenerates `docs/`. - `models/` — Mongo document structs (`Event`, `User`, `Response`, `Folder`, `Attendee`, `Calendar`, `Set`, `Otp`, `FriendRequest`, `Location`, `DailyUserLog`). - `db/` — Mongo accessors per model (`events.go`, `users.go`, `folders.go`, `analytics.go`, `utils.go`) plus `init.go`. Treat this as the only layer that talks to Mongo. - `services/` — external integrations. Notable: `calendar/` (Google, Outlook/Graph, Apple CalDAV via `jonyTF/go-webdav`, generic ICS), `auth/`, `contacts/`, `gcloud/` (Cloud Tasks for scheduled jobs), `listmonk/`, `microsoftgraph/`. @@ -51,7 +51,7 @@ For local frontend → local backend, set `CORS_ORIGINS=http://localhost:8080` i - `logger/` — wraps log file (`logs.log`) + stdout via `gin.DefaultWriter`. ### Frontend (Vue 2 SPA) -- `src/router/index.js` — routes (`Landing`, `Home`, `Event`, `Group`, `Friends`, `Settings`, `SignIn`/`SignUp`/`Auth`, `StripeRedirect`, etc. — see `src/views/`). +- `src/router/index.js` — routes (`Landing`, `Home`, `Event`, `Group`, `Friends`, `Settings`, `SignIn`/`SignUp`/`Auth`, etc. — see `src/views/`). - `src/store/index.js` — single Vuex store (auth user, events, snackbar, dialogs). - `src/components/` — organized by feature folder (`event/`, `groups/`, `home/`, `landing/`, `pricing/`, `settings/`, `schedule_overlap/`, `calendar_permission_dialogs/`, `sign_up_form/`, `general/`) plus top-level shared components. - `src/utils/` — date math (`date_utils.js`, uses `dayjs`/`moment`/`spacetime`), `fetch_utils.js` (API client), `plugin_utils.js` (handles the postMessage plugin API — see `PLUGIN_API_README.md`), `sign_in_utils.js`, `location_utils.js`, `services/` (calendar-provider abstractions on the client side). diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 145521cfe..b6d3e5ae4 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -106,27 +106,6 @@ Create `server/.env` from the template (`server/.env.template`). | `ENCRYPTION_KEY` | Key for encrypting sensitive data (generate with `openssl rand -base64 32`) | | `SESSION_SECRET` | Session cookie encryption key (generate with `openssl rand -base64 32`) | -#### Optional — Payments - -New purchases go through [Polar](https://polar.sh). Stripe is only kept for subscribers who signed up before the move, whose subscriptions still renew on Stripe. - -| Variable | Description | -| ----------------------- | ------------------------------------------------------------------ | -| `POLAR_ACCESS_TOKEN` | Polar Organization Access Token | -| `POLAR_WEBHOOK_SECRET` | Polar webhook endpoint secret | -| `POLAR_SERVER` | `sandbox` or `production` (default: `production`) | -| `POLAR_*_PRODUCT_ID` | Polar product IDs for each plan (monthly, yearly, and student variants; lifetime is disabled) | -| `STRIPE_API_KEY` | Stripe API key (legacy subscribers only) | -| `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret (legacy subscribers only) | - -Polar setup: - -1. Create one product per plan. Each Polar product has a single pricing model, so monthly and yearly are separate products. -2. Create an Organization Access Token with the `checkouts:write`, `products:read`, and `customer_sessions:write` scopes. -3. Add a webhook endpoint at `https:///api/polar/webhook` with format **Raw** and API version **2026-10**, subscribed to `order.paid`, `subscription.active`, `subscription.past_due`, `subscription.revoked`, and `subscription.migrated`. - -For local development, `polar listen http://localhost:3002/api/polar/webhook` forwards webhooks and prints the secret to use for `POLAR_WEBHOOK_SECRET`. - #### Optional — Additional Calendars | Variable | Description | diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 32608a4ad..1e1dbe5ed 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,7 +11,6 @@ "@gtm-support/vue2-gtm": "^2.0.0", "@rive-app/canvas": "^2.10.0", "bson-objectid": "^2.0.4", - "canvas-confetti": "^1.9.3", "color": "^4.2.3", "copy-image-clipboard": "^2.1.2", "core-js": "^3.35.1", @@ -4940,16 +4939,6 @@ } ] }, - "node_modules/canvas-confetti": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", - "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", - "license": "ISC", - "funding": { - "type": "donate", - "url": "https://www.paypal.me/kirilvatev" - } - }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index a21d12254..c2b83a94d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,6 @@ "@gtm-support/vue2-gtm": "^2.0.0", "@rive-app/canvas": "^2.10.0", "bson-objectid": "^2.0.4", - "canvas-confetti": "^1.9.3", "color": "^4.2.3", "copy-image-clipboard": "^2.1.2", "core-js": "^3.35.1", diff --git a/frontend/public/ads.txt b/frontend/public/ads.txt deleted file mode 100644 index a77800105..000000000 --- a/frontend/public/ads.txt +++ /dev/null @@ -1 +0,0 @@ -google.com, pub-4082178684015354, DIRECT, f08c47fec0942fa0 \ No newline at end of file diff --git a/frontend/public/index.html b/frontend/public/index.html index a300a8a4a..926d93b6e 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -15,7 +15,6 @@ })(window, document, "script", "dataLayer", "GTM-M677X6V") - diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 176178b5c..0e0222311 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -16,10 +16,6 @@ :no-tabs="newDialogOptions.eventOnly" :folder-id="newDialogOptions.folderId" /> -
- Premium + Supporter @@ -61,14 +57,14 @@ > Give feedback - + diff --git a/frontend/src/components/UserAvatarContent.vue b/frontend/src/components/UserAvatarContent.vue index 6bc63591f..8c9b347f0 100644 --- a/frontend/src/components/UserAvatarContent.vue +++ b/frontend/src/components/UserAvatarContent.vue @@ -1,5 +1,10 @@