Skip to content

Commit ba400a3

Browse files
committed
refactor: error tracker
1 parent 46d404b commit ba400a3

File tree

3 files changed

+216
-1
lines changed

3 files changed

+216
-1
lines changed

.github/copilot-instructions.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# GitHub Copilot Instructions for datum.net
2+
3+
## Project Overview
4+
5+
This is the official Datum Inc. marketing website - an Astro-based static site with SSR capabilities, built with TypeScript, Tailwind CSS v4, and AlpineJS. The site serves multiple purposes: marketing pages, documentation (via Starlight), blog, handbook, changelog, and interactive features like roadmap voting.
6+
7+
**Tech Stack:** Astro 5, TypeScript, Tailwind CSS v4, AlpineJS, Starlight, Postgres, MDX
8+
9+
## Architecture & Key Patterns
10+
11+
### Content Collections Architecture
12+
13+
The site uses Astro's Content Collections extensively (`src/content.config.ts`). All content is type-safe with Zod schemas:
14+
15+
- **Collections:** `pages`, `about`, `blog`, `authors`, `categories`, `handbooks`, `changelog`, `features`, `huddles`, `docs`
16+
- **Pattern:** Use `getCollectionEntry()` helper from `@utils/collectionUtils` instead of raw `getEntry()` - it provides better error handling
17+
- **Loaders:** Content uses `glob` loaders, docs use `docsLoader()` from Starlight
18+
- **References:** Collections can reference each other via `reference('collectionName')`
19+
20+
Example:
21+
22+
```typescript
23+
const page = await getCollectionEntry('pages', 'pricing');
24+
const huddles = await getCollection('huddles');
25+
```
26+
27+
### Import Path Aliases (tsconfig.json)
28+
29+
Always use path aliases for imports:
30+
31+
- `@components/*` - UI components
32+
- `@layouts/*` - Page layouts
33+
- `@utils/*` - Utility functions
34+
- `@libs/*` - Library code (datum, github, postgres, oidc)
35+
- `@content/*` - Content files
36+
- `@data/*` - JSON data files
37+
- `@v1/*` - Legacy styles/components
38+
39+
### Component Patterns
40+
41+
**Astro Components:**
42+
43+
- Use `.astro` extension for templating
44+
- Props are accessed via `Astro.props`
45+
- Use `class` prop (not `className`) for styling: `Astro.props.class`
46+
- Middleware provides `Astro.locals` (e.g., `Astro.locals.starCount()`)
47+
48+
**AlpineJS Integration:**
49+
50+
- Interactive components use `x-data`, `x-show`, `x-if`, `@click` directives
51+
- AlpineJS initialized in `src/entrypoint.ts` with `@alpinejs/collapse` plugin
52+
- Common pattern: `x-data="{ open: false }"` for toggle states
53+
- Use `x-collapse` for expandable sections (see `handbook/Sidebar.astro`)
54+
55+
### Starlight Documentation
56+
57+
The `/docs` route is powered by Starlight with heavy customization:
58+
59+
- Override components in `src/components/starlight/`
60+
- Custom sidebar, header, footer, search components
61+
- Access Starlight context: `Astro.locals.starlightRoute` (has `hasSidebar`, `toc`, `sidebar`)
62+
- Translations: `Astro.locals.t('search.label')`
63+
- Glossary plugin: `@libs/server/glossary.js`
64+
65+
### Actions (Server Functions)
66+
67+
Astro Actions in `src/actions/` provide type-safe server endpoints:
68+
69+
```typescript
70+
import { defineAction } from 'astro:actions';
71+
import { z } from 'astro:content';
72+
73+
export const vote = defineAction({
74+
input: z.object({ userId: z.string(), issueId: z.string() }),
75+
handler: async (input) => {
76+
/* ... */
77+
},
78+
});
79+
```
80+
81+
Used for roadmap voting, OIDC authentication, etc.
82+
83+
### Database Integration
84+
85+
- **Postgres:** Connection management in `src/libs/postgres.ts`
86+
- Lazy connection: `dbConnect()` creates connection on first use
87+
- Tables: `votes`, `issues`, `user_votes`
88+
- Always use environment variables: `import.meta.env.POSTGRES_USER || process.env.POSTGRES_USER`
89+
90+
### External Integrations
91+
92+
**GitHub API:** `src/libs/github.ts` and `src/libs/datum.ts`
93+
94+
- Fetch stargazer count (cached in middleware)
95+
- Roadmap issues from `datum-cloud/enhancements` repo
96+
- Changelogs from GitHub Discussions
97+
- Uses `octokit` library with GraphQL queries
98+
99+
**OIDC Authentication:** `src/libs/oidc.ts`
100+
101+
- OpenID Connect client for Datum platform integration
102+
- PKCE flow for authorization
103+
- Environment vars: `AUTH_OIDC_ISSUER`, `AUTH_OIDC_CLIENT_ID`, etc.
104+
105+
### Caching Strategy
106+
107+
File-based caching in `src/libs/cache.ts`:
108+
109+
```typescript
110+
const cache = new Cache('.cache');
111+
if (cache.has('key')) return cache.get('key');
112+
cache.set('key', value, ttl); // ttl in milliseconds
113+
```
114+
115+
Used for GitHub API responses (5-10 min TTL)
116+
117+
## Development Workflow
118+
119+
### Commands
120+
121+
```bash
122+
npm run dev # Dev server at localhost:4321
123+
npm run build # Production build + Pagefind indexing
124+
npm run lint # ESLint check
125+
npm run lint:fix # Auto-fix linting issues
126+
npm run lint:md:fix # Fix markdown issues (MDX in src/content/)
127+
npm run format # Prettier formatting
128+
npm run test:e2e # Playwright E2E tests
129+
```
130+
131+
### Critical Build Steps
132+
133+
1. Must run `npm run build` once before dev to generate Pagefind search indices
134+
2. Pagefind indexes: main site (`dist/pagefind`) and blog-only (`dist/pagefind-blog`)
135+
3. Dev mode copies these to `public/` directory
136+
137+
### Environment Variables
138+
139+
- Always check both `import.meta.env.VAR` AND `process.env.VAR`
140+
- Pattern: `import.meta.env.SITE_URL || process.env.SITE_URL || 'fallback'`
141+
- See `.env.example` for required vars
142+
143+
### Markdown/MDX Content
144+
145+
**Linting:** Relaxed markdownlint rules (`.markdownlint.json`)
146+
147+
- Allows inline HTML/JSX (MD033) for MDX components
148+
- No line length limits (MD013)
149+
- Flexible for React/Astro component integration
150+
151+
**Front matter schemas:** Defined in `src/content.config.ts` with Zod
152+
153+
- Required: `title`
154+
- Common: `description`, `date`, `slug`, `order`, `draft`, `meta` (SEO)
155+
156+
## Code Quality
157+
158+
### ESLint Configuration
159+
160+
- Flat config format (`eslint.config.mjs`)
161+
- TypeScript, Astro, MDX support
162+
- **Accessibility:** Most jsx-a11y rules disabled (intentional for marketing site)
163+
- Ignores: `dist/`, `public/pagefind*/`, `src/content/`
164+
165+
### TypeScript
166+
167+
- Strict mode enabled
168+
- Use `Astro.props as TypeName` for component props
169+
- Types in `src/types/` (e.g., `common.ts` has `LayoutProps`)
170+
171+
### Styling
172+
173+
- **Tailwind CSS v4:** Config in `tailwind.starlight.config.cjs` (Starlight-specific)
174+
- Vite plugin: `@tailwindcss/vite`
175+
- No preflight for Starlight pages (`corePlugins: { preflight: false }`)
176+
- Custom styles in `src/v1/styles/`
177+
178+
## Docker & Deployment
179+
180+
Multi-stage Dockerfile:
181+
182+
- **Development:** Hot-reload, mounted source, port 4321
183+
- **Production:** Optimized build, standalone Node server
184+
- Entry point: `dist/server/entry.mjs` (SSR mode with `@astrojs/node` adapter)
185+
- Environment: Alpine Linux, Node 24
186+
187+
Kubernetes configs in `config/` (base, dev, gateway)
188+
189+
## Common Pitfalls
190+
191+
1. **Pagefind Search:** Must build once before dev mode works
192+
2. **Content Collections:** Always await `getCollection()` / `getCollectionEntry()`
193+
3. **AlpineJS:** Components need `x-data` to initialize Alpine context
194+
4. **Middleware:** `Astro.locals` only available after middleware runs
195+
5. **Images:** Use `image()` in schemas, not plain strings for local images
196+
6. **Trailing Slashes:** Configured as `always` in `astro.config.mjs`
197+
7. **Routes:** Dynamic routes use `[slug].astro` or `[...slug].astro` patterns
198+
199+
## File Organization
200+
201+
- `src/pages/` - File-based routing
202+
- `src/components/` - Organized by feature (blog/, handbook/, starlight/, etc.)
203+
- `src/content/` - MDX content collections
204+
- `src/libs/` - Reusable libraries (github, postgres, oidc, cache)
205+
- `src/utils/` - Helper functions (dateUtils, imageUtils, collectionUtils)
206+
- `src/actions/` - Server actions (vote, auth)
207+
- `public/` - Static assets (fonts, images, scripts)
208+
209+
## Testing
210+
211+
Playwright for E2E testing:
212+
213+
- Tests in `tests/e2e/`
214+
- Reports in `playwright-report/` (gitignored)
215+
- CI-configured with retries and screenshots on failure

src/pages/404.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const description = 'The page you are looking for does not exist.';
4040

4141
{
4242
import.meta.env.MODE === 'production' && (
43-
<script>import '/src/v1/scripts/404tracking.js';</script>
43+
<script>import '/src/v1/scripts/error-tracker.js';</script>
4444
)
4545
}
4646
</Layout>

0 commit comments

Comments
 (0)