Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ARG NODE_VERSION=20.19.0

FROM node:${NODE_VERSION}-bookworm

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
sudo \
&& rm -rf /var/lib/apt/lists/*

RUN echo "node ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/node \
&& chmod 0440 /etc/sudoers.d/node

ENV PNPM_HOME=/home/node/.local/share/pnpm
ENV PATH=${PNPM_HOME}:${PATH}

WORKDIR /workspaces/f3-nation

RUN corepack enable \
&& corepack prepare pnpm@8.15.1 --activate

USER node
31 changes: 31 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "f3-nation",
"dockerComposeFile": ["docker-compose.yml"],
"service": "dev",
"workspaceFolder": "/workspaces/f3-nation",
"shutdownAction": "stopCompose",
"remoteUser": "node",
"forwardPorts": [3000, 5432],
"postCreateCommand": "corepack enable && corepack prepare pnpm@8.15.1 --activate && pnpm config set confirmModulesPurge false && CI=1 pnpm install",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-azuretools.vscode-docker"
],
"settings": {
"editor.formatOnSave": true,
"eslint.format.enable": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"typescript.tsdk": "node_modules/typescript/lib",
"terminal.integrated.defaultProfile.linux": "bash"
}
}
}
}
34 changes: 34 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: "3.9"

services:
dev:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ..:/workspaces/f3-nation:cached
- pnpm-store:/home/node/.local/share/pnpm/store
command: sleep infinity
depends_on:
- postgres

postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: f3_dev
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d postgres"]
interval: 10s
timeout: 5s
retries: 5

volumes:
pnpm-store:
postgres-data:
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,8 @@ test-results/
# sentry
.env.sentry-build-plugin

# pnpm store
.pnpm-store/

pr.md
.eslintcache
.eslintcache
97 changes: 96 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,100 @@
"next/router.d.ts",
"next/dist/client/router.d.ts"
],
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"chat.tools.terminal.autoApprove": {
"/^cd /home/evan/ml/f3-nation && pnpm --filter f3-nation-slackbot typecheck$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm --filter f3-nation-slackbot lint$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot typecheck 2>&1 \\| head -100$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F @acme/api typecheck 2>&1 \\| head -100$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F @acme/db typecheck 2>&1 \\| head -100$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot lint 2>&1 \\| head -80$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot typecheck 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm tsc --noEmit 2>&1 \\| head -80$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm tsc --noEmit 2>&1 \\| head -100$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm tsc --noEmit 2>&1 \\| head -50$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm exec eslint src/features/backblast/edit-form-handlers\\.ts 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm exec tsc --noEmit 2>&1 \\| head -30$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm exec tsc --noEmit 2>&1 \\| head -15$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/apps/slackbot && pnpm exec eslint src/features/backblast/\\*\\.ts 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -C apps/slackbot typecheck 2>&1 \\| head -80$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -C apps/slackbot lint 2>&1 \\| tail -20$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot typecheck 2>&1 \\| head -60$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F @acme/api typecheck 2>&1 \\| head -60$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot lint 2>&1 \\| grep -A 2 \"file-upload\"$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot lint 2>&1 \\| grep -E \"\\(error\\|warning\\)\" \\| head -20$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F f3-nation-slackbot lint 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation && pnpm -F @acme/api lint 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"/^cd /home/evan/ml/f3-nation/packages/api && npx eslint src/router/upload\\.ts 2>&1$/": {
"approve": true,
"matchCommandLine": true
},
"pnpm": true
}
}
22 changes: 22 additions & 0 deletions apps/api/src/app/docs/openapi.json/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,24 @@ As of February 1, 2026, regional admins can only create read-only API keys. If y
name: "api",
tags: [
"api-key",
"attendance",
"event",
"event-instance",
"event-tag",
"event-type",
"location",
"mail",
"org",
"ping",
"position",
"request",
"user",
],
},
{
name: "slack",
tags: ["slack"],
},
{
name: "map",
tags: ["feedback", "map.event", "map.location", "revalidate"],
Expand All @@ -151,12 +159,25 @@ As of February 1, 2026, regional admins can only create read-only API keys. If y
name: "api-key",
description: "API key management for programmatic access",
},
{
name: "attendance",
description: "Workout attendance tracking and management",
},
{ name: "event", description: "Workout event management" },
{
name: "event-instance",
description: "Individual event instance management",
},
{ name: "event-tag", description: "Event tagging and categorization" },
{ name: "event-type", description: "Event type/category management" },
{ name: "feedback", description: "User feedback submission" },
{
name: "location",
description: "Physical location management for workouts",
},
{ name: "mail", description: "Email sending and management" },
{ name: "map", description: "Map-related utilities and revalidation" },
{ name: "map.location", description: "Map location data and search" },
{
name: "org",
description: "Organization management (regions, AOs, etc.)",
Expand All @@ -167,6 +188,7 @@ As of February 1, 2026, regional admins can only create read-only API keys. If y
description: "Position and role management for organizations",
},
{ name: "request", description: "Data change request workflow" },
{ name: "slack", description: "Slack integration and management" },
{ name: "user", description: "User account management" },
{
name: "map.event",
Expand Down
26 changes: 26 additions & 0 deletions apps/slackbot/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Slack Bot Environment Variables

# Slack App Credentials
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_SIGNING_SECRET=your-signing-secret
SLACK_APP_TOKEN=xapp-your-app-token

# Development Mode
LOCAL_DEVELOPMENT=true
SOCKET_MODE=true

# External Services
STATS_URL=https://pax-vault.f3nation.com

# Optional: Strava Integration
# STRAVA_CLIENT_ID=
# STRAVA_CLIENT_SECRET=

# Optional: AWS S3 (for image uploads)
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_BUCKET_NAME=

# API Configuration
API_URL=http://localhost:3000/api/v1
SLACKBOT_API_KEY=your-api-key-here
Loading
Loading