First Init
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# Error Monitoring & Logging
|
||||
|
||||
## Overview
|
||||
|
||||
The WorkRoot site uses a two-layer monitoring approach:
|
||||
|
||||
1. **Structured Logger** (`src/utils/logger.ts`) — always active, zero dependencies
|
||||
2. **Sentry Integration** (`src/utils/sentry.ts`) — optional, activated via `SENTRY_DSN` env var
|
||||
|
||||
---
|
||||
|
||||
## Files Created / Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `src/utils/logger.ts` | **New** — structured logger |
|
||||
| `src/utils/sentry.ts` | **New** — Sentry HTTP integration |
|
||||
| `src/middleware.ts` | **Updated** — logs all requests + SSR errors |
|
||||
| `src/pages/api/contact.ts` | **Updated** — structured logs + Sentry on email failure |
|
||||
| `src/pages/api/newsletter.ts` | **Updated** — structured logs + Sentry on SMTP failure |
|
||||
| `.env.example` | **Updated** — added `SENTRY_DSN`, `LOG_LEVEL`, `RELEASE_VERSION` |
|
||||
|
||||
---
|
||||
|
||||
## Structured Logger
|
||||
|
||||
### Usage
|
||||
|
||||
```typescript
|
||||
import { logger, logApiRequest } from '../../utils/logger';
|
||||
|
||||
// General logging
|
||||
logger.debug('scope', 'message', { key: 'value' });
|
||||
logger.info('scope', 'message', { key: 'value' });
|
||||
logger.warn('scope', 'message', { key: 'value' });
|
||||
logger.error('scope', 'message', { key: 'value' });
|
||||
|
||||
// API request logging
|
||||
logApiRequest({
|
||||
scope: 'api.contact',
|
||||
method: 'POST',
|
||||
path: '/api/contact',
|
||||
status: 200,
|
||||
ip: clientAddress,
|
||||
durationMs: Date.now() - startTime,
|
||||
meta: { subject: formData.subject },
|
||||
});
|
||||
```
|
||||
|
||||
### Output Format
|
||||
|
||||
**Development** — human-readable with color:
|
||||
```
|
||||
[INFO] 2026-03-21T08:00:00.000Z [api.contact] POST /api/contact 200 {"durationMs":42}
|
||||
[ERROR] 2026-03-21T08:00:01.000Z [api.contact] Email delivery failed {"error":"..."}
|
||||
```
|
||||
|
||||
**Production** — JSON for log aggregation:
|
||||
```json
|
||||
{"level":"info","scope":"api.contact","message":"POST /api/contact 200","timestamp":"2026-03-21T08:00:00.000Z","durationMs":42}
|
||||
```
|
||||
|
||||
### Log Levels
|
||||
|
||||
| Level | When |
|
||||
|-------|------|
|
||||
| `debug` | Verbose request tracing (dev only by default) |
|
||||
| `info` | Successful operations, informational events |
|
||||
| `warn` | Rate-limit hits, 4xx errors, degraded operations |
|
||||
| `error` | 5xx errors, email failures, unhandled exceptions |
|
||||
|
||||
Configure minimum log level via `LOG_LEVEL` env var (`debug`/`info`/`warn`/`error`).
|
||||
|
||||
---
|
||||
|
||||
## Sentry Integration
|
||||
|
||||
### Setup
|
||||
|
||||
1. Create a project at [sentry.io](https://sentry.io) (Node.js platform)
|
||||
2. Copy the DSN from **Settings → Client Keys (DSN)**
|
||||
3. Add to your environment:
|
||||
|
||||
```env
|
||||
SENTRY_DSN=https://xxx@oXXXXXX.ingest.sentry.io/XXXXXXX
|
||||
RELEASE_VERSION=1.0.0
|
||||
```
|
||||
|
||||
No SDK installation required — the integration uses Sentry's HTTP store API directly.
|
||||
|
||||
### Usage
|
||||
|
||||
```typescript
|
||||
import { captureException, captureMessage } from '../../utils/sentry';
|
||||
|
||||
// Capture an exception (also logs via structured logger)
|
||||
await captureException(error, {
|
||||
scope: 'api.contact',
|
||||
user: { ip: clientAddress },
|
||||
extra: { email: formData.email },
|
||||
tags: { feature: 'contact-form' },
|
||||
});
|
||||
|
||||
// Capture a message
|
||||
await captureMessage('Rate limit exceeded', 'warning', {
|
||||
scope: 'api.contact',
|
||||
extra: { ip },
|
||||
});
|
||||
```
|
||||
|
||||
### What Gets Captured
|
||||
|
||||
| Event | Sentry Level | Location |
|
||||
|-------|-------------|----------|
|
||||
| SSR middleware crash | error | `src/middleware.ts` |
|
||||
| Contact form email failure | error | `src/pages/api/contact.ts` |
|
||||
| Newsletter SMTP failure | error | `src/pages/api/newsletter.ts` |
|
||||
|
||||
### Without SENTRY_DSN
|
||||
|
||||
All calls to `captureException` / `captureMessage` fall back to structured logger only. **No errors are swallowed** — monitoring degrades gracefully.
|
||||
|
||||
---
|
||||
|
||||
## Middleware Request Logging
|
||||
|
||||
All HTTP requests pass through `src/middleware.ts`, which now logs:
|
||||
|
||||
- **5xx** → `error` level (also tries to capture in Sentry)
|
||||
- **4xx** → `warn` level
|
||||
- **All others** → `debug` level (dev only)
|
||||
|
||||
Duration is measured from request start to response completion.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```env
|
||||
# Required for Sentry error tracking
|
||||
SENTRY_DSN=https://xxx@oXXXXXX.ingest.sentry.io/XXXXXXX
|
||||
|
||||
# Optional — minimum log level (default: info in prod, debug in dev)
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Optional — used for Sentry release tracking
|
||||
RELEASE_VERSION=1.0.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Upgrading to Full Sentry SDK
|
||||
|
||||
For richer features (performance monitoring, session replay, source maps):
|
||||
|
||||
```bash
|
||||
npm install @sentry/node
|
||||
```
|
||||
|
||||
Then replace `src/utils/sentry.ts` with:
|
||||
|
||||
```typescript
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
Sentry.init({
|
||||
dsn: import.meta.env.SENTRY_DSN,
|
||||
environment: import.meta.env.PROD ? 'production' : 'development',
|
||||
release: process.env.RELEASE_VERSION,
|
||||
tracesSampleRate: 0.1, // 10% of transactions
|
||||
});
|
||||
|
||||
export const captureException = (err: unknown, ctx?: object) =>
|
||||
Sentry.captureException(err, ctx ? { extra: ctx as Record<string, unknown> } : undefined);
|
||||
|
||||
export const captureMessage = (msg: string, level = 'info') =>
|
||||
Sentry.captureMessage(msg, level as Sentry.SeverityLevel);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Log Aggregation (Production)
|
||||
|
||||
Since production output is newline-delimited JSON, it integrates with:
|
||||
|
||||
- **Logtail / Better Stack** — point log drain at your server stdout
|
||||
- **Datadog** — use their Node.js log agent
|
||||
- **Render / Railway / Fly.io** — all capture stdout automatically; pipe to their log service
|
||||
- **Self-hosted** — any log shipper that reads Docker/PM2 stdout (Filebeat, Promtail, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Verify structured logging is working:
|
||||
|
||||
```bash
|
||||
# Development — see colored output
|
||||
npm run dev
|
||||
# Visit http://localhost:4321/api/health → should see DEBUG log
|
||||
|
||||
# Production — see JSON output
|
||||
NODE_ENV=production node server.mjs
|
||||
```
|
||||
|
||||
Verify Sentry is working:
|
||||
|
||||
```bash
|
||||
# Set SENTRY_DSN in .env, then trigger an error:
|
||||
curl -X POST http://localhost:4321/api/contact \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Test","email":"bad@","subject":"other","message":"test"}'
|
||||
# Check your Sentry dashboard for the captured event
|
||||
```
|
||||
@@ -0,0 +1,290 @@
|
||||
# Form Backend Integration
|
||||
|
||||
**Agent**: backend-specialist
|
||||
**Date**: 2026-03-21
|
||||
**Status**: Complete ✓
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Two API endpoints handle form submissions for the WorkRoot site:
|
||||
|
||||
| Endpoint | File | Purpose |
|
||||
|----------|------|---------|
|
||||
| `POST /api/contact` | `src/pages/api/contact.ts` | Contact form submissions |
|
||||
| `POST /api/newsletter` | `src/pages/api/newsletter.ts` | Newsletter subscriptions |
|
||||
|
||||
Both endpoints include server-side validation, rate limiting, spam protection, and graceful degradation when optional dependencies (SMTP, newsletter providers) are not configured.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### Contact Form (`/api/contact`)
|
||||
|
||||
**Flow:**
|
||||
1. Client submits form → `POST /api/contact` (JSON body)
|
||||
2. Rate limit check (5 requests / IP / hour, sliding window)
|
||||
3. Honeypot field check (silent success if bot detected)
|
||||
4. Server-side field validation
|
||||
5. Email delivery via SMTP (nodemailer) — logs to console if SMTP not configured
|
||||
6. JSON response returned
|
||||
|
||||
**Fields validated:**
|
||||
- `name` — required, 2–100 characters
|
||||
- `email` — required, valid format, max 254 chars
|
||||
- `phone` — optional; if present, must match phone regex
|
||||
- `subject` — required, allowlist enum (web-development, mobile-development, cloud-services, ai-ml, consulting, support, other)
|
||||
- `message` — required, 10–5000 characters
|
||||
- `website` — honeypot, must be empty
|
||||
|
||||
**Rate limit:** 5 requests per IP per hour
|
||||
|
||||
---
|
||||
|
||||
### Newsletter (`/api/newsletter`)
|
||||
|
||||
**Flow:**
|
||||
1. Client submits email → `POST /api/newsletter` (JSON body)
|
||||
2. Rate limit check (3 requests / IP / hour)
|
||||
3. Email format validation
|
||||
4. Subscribe via configured provider (Mailchimp → ConvertKit → SMTP notification → log-only)
|
||||
5. JSON response returned
|
||||
|
||||
**Rate limit:** 3 requests per IP per hour
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Set these environment variables (see `.env.example`):
|
||||
|
||||
### Email (SMTP) — for contact form delivery and newsletter fallback
|
||||
```env
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your_email@example.com
|
||||
SMTP_PASS=your_app_password
|
||||
CONTACT_EMAIL=hello@workroot.in
|
||||
```
|
||||
|
||||
> **Gmail tip:** Enable 2FA, then create an App Password at https://myaccount.google.com/apppasswords
|
||||
|
||||
### Newsletter — pick ONE provider
|
||||
|
||||
**Mailchimp (recommended):**
|
||||
```env
|
||||
MAILCHIMP_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us1
|
||||
MAILCHIMP_LIST_ID=abc123def456
|
||||
MAILCHIMP_DC=us1
|
||||
```
|
||||
Uses double opt-in (`status: "pending"`). Handles already-subscribed gracefully.
|
||||
|
||||
**ConvertKit:**
|
||||
```env
|
||||
CONVERTKIT_API_KEY=your_api_key
|
||||
CONVERTKIT_FORM_ID=1234567
|
||||
```
|
||||
|
||||
> If no provider is configured, submissions are logged to server console. Safe for development and staging.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
### nodemailer (installed)
|
||||
The SMTP functionality requires `nodemailer`. It is installed as a production dependency:
|
||||
|
||||
```bash
|
||||
npm install nodemailer
|
||||
npm install --save-dev @types/nodemailer
|
||||
```
|
||||
|
||||
Both are now in `package.json`. The dynamic import (`await import('nodemailer')`) in the API routes handles the case where the module is unavailable with graceful degradation.
|
||||
|
||||
---
|
||||
|
||||
## Graceful Degradation Matrix
|
||||
|
||||
| Config state | Contact form | Newsletter |
|
||||
|---|---|---|
|
||||
| SMTP not configured | Logs submission to console, returns 200 | Falls through to next provider |
|
||||
| SMTP configured, nodemailer unavailable | Warns and logs only, returns 200 | Warns and logs only, returns 200 |
|
||||
| No newsletter provider | — | Logs to console, returns 200 |
|
||||
| SMTP set, no newsletter provider | Sends email | Falls back to SMTP notification |
|
||||
| All configured | Sends HTML email | Sends to Mailchimp/ConvertKit |
|
||||
|
||||
This prevents the site from breaking in any environment, including when secrets aren't yet configured.
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
### Spam Protection
|
||||
- **Honeypot field**: `website` input hidden from users via CSS (`position: absolute; left: -9999px`). Bots that fill all fields are detected server-side and receive a silent 200 response.
|
||||
- **Rate limiting**: In-memory sliding window per IP address. Configurable constants at the top of each API file:
|
||||
- Contact: `RATE_LIMIT_MAX_REQUESTS = 5` per hour
|
||||
- Newsletter: `RATE_LIMIT_MAX_REQUESTS = 3` per hour
|
||||
|
||||
### Input Validation
|
||||
- All input validated server-side regardless of client-side checks
|
||||
- String lengths enforced to prevent DoS via large payloads
|
||||
- Subject field uses an allowlist (enum) to prevent injection
|
||||
- HTML in email templates uses `escapeHtml()` to prevent XSS in email clients
|
||||
|
||||
### CORS
|
||||
- Production: `Access-Control-Allow-Origin: https://workroot.in`
|
||||
- Development: `Access-Control-Allow-Origin: *`
|
||||
- Preflight `OPTIONS` handlers implemented on both endpoints
|
||||
|
||||
### Rate Limit Response Headers
|
||||
Both endpoints return standard rate limit headers on every response:
|
||||
```
|
||||
X-RateLimit-Limit: 5
|
||||
X-RateLimit-Remaining: 4
|
||||
X-RateLimit-Reset: 1742000000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Response Format
|
||||
|
||||
All responses follow a consistent structure:
|
||||
|
||||
**Success (200):**
|
||||
```json
|
||||
{ "success": true, "message": "Human-readable success message" }
|
||||
```
|
||||
|
||||
**Validation error (422):**
|
||||
```json
|
||||
{ "success": false, "error": "Specific validation error" }
|
||||
```
|
||||
|
||||
**Rate limited (429):**
|
||||
```json
|
||||
{ "success": false, "error": "Too many requests. Please try again later." }
|
||||
```
|
||||
|
||||
**Server error (500):**
|
||||
```json
|
||||
{ "success": false, "error": "Failed to send message. Please try again or email us directly." }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Client Integration
|
||||
|
||||
### Contact form (`src/pages/contact.astro`)
|
||||
Posts JSON to `/api/contact`. Handles all response states:
|
||||
- Success → toast notification + form reset
|
||||
- Validation error → toast with specific message
|
||||
- Rate limit (429) → error toast
|
||||
- Network error → error toast
|
||||
|
||||
### Newsletter form (`src/components/Footer.astro`)
|
||||
Posts JSON to `/api/newsletter`. Handles all response states:
|
||||
- Success → inline green message + form reset
|
||||
- Error → inline red message
|
||||
- Network error → inline red message
|
||||
- Message auto-hides after 5 seconds
|
||||
|
||||
---
|
||||
|
||||
## Logging & Monitoring
|
||||
|
||||
Both endpoints use `src/utils/logger.ts` for structured logging:
|
||||
- Development: colored console output
|
||||
- Production: JSON output for log aggregators (Logtail, Datadog, etc.)
|
||||
|
||||
Errors are captured via `src/utils/sentry.ts` (optional — only active when `SENTRY_DSN` env var is set).
|
||||
|
||||
Each API request is logged with:
|
||||
- Method, path, status code
|
||||
- IP address
|
||||
- Duration in milliseconds
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Test the endpoints manually with curl:
|
||||
|
||||
```bash
|
||||
# Contact form - success case
|
||||
curl -X POST http://localhost:4321/api/contact \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Test User","email":"test@example.com","subject":"consulting","message":"Hello, I need help with a project."}'
|
||||
|
||||
# Newsletter - success case
|
||||
curl -X POST http://localhost:4321/api/newsletter \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"subscriber@example.com"}'
|
||||
|
||||
# Test honeypot (should return 200 silently)
|
||||
curl -X POST http://localhost:4321/api/contact \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Bot","email":"bot@spam.com","subject":"other","message":"Buy cheap stuff now!","website":"http://spam.com"}'
|
||||
|
||||
# Test rate limiting (run 4+ times to trigger 429 on newsletter)
|
||||
for i in 1 2 3 4; do
|
||||
curl -s -o /dev/null -w "%{http_code}\n" \
|
||||
-X POST http://localhost:4321/api/newsletter \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com"}'
|
||||
done
|
||||
```
|
||||
|
||||
Playwright tests are located at:
|
||||
- `tests/contact-form.spec.ts` — contact form UI and API
|
||||
- `tests/newsletter-subscription.spec.ts` — newsletter UI and API
|
||||
- `tests/api-integration.spec.ts` — API endpoint integration tests
|
||||
- `tests/e2e-form-interactions.spec.ts` — form interaction flows
|
||||
|
||||
Run all form tests:
|
||||
```bash
|
||||
npm run test:forms
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## In-Memory Rate Limiter Notes
|
||||
|
||||
The current rate limiter is in-memory (per process). This means:
|
||||
|
||||
- ✅ Works correctly for single-instance deployments (VPS, single container)
|
||||
- ⚠️ Resets on server restart
|
||||
- ⚠️ Not shared across multiple instances (e.g., PM2 cluster mode)
|
||||
|
||||
For multi-instance deployments, upgrade to Redis-backed rate limiting (see Future Improvements).
|
||||
|
||||
---
|
||||
|
||||
## Alternative: FormSpree (No-code option)
|
||||
|
||||
If you prefer a managed third-party service without SMTP configuration:
|
||||
|
||||
1. Sign up at https://formspree.io
|
||||
2. Create a form and get your form ID (e.g. `xpwzgkab`)
|
||||
3. Replace the fetch URL in `contact.astro`:
|
||||
```javascript
|
||||
const response = await fetch('https://formspree.io/f/xpwzgkab', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
```
|
||||
|
||||
The existing custom API endpoint can remain for future migration back to self-hosted.
|
||||
|
||||
---
|
||||
|
||||
## Future Improvements
|
||||
|
||||
- [ ] Persist rate limit state in Redis for multi-instance PM2 cluster deployments
|
||||
- [ ] Add CAPTCHA (hCaptcha or Cloudflare Turnstile) as additional spam layer
|
||||
- [ ] Store contact submissions in a database for CRM integration
|
||||
- [ ] Add confirmation/welcome email for newsletter signups (double opt-in flow)
|
||||
- [ ] Webhook notifications to Slack/Discord on new contact submissions
|
||||
- [ ] Admin dashboard to view contact form submissions
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
agent_id: a28de37e-1a69-48d0-8224-13a1d5bf646e
|
||||
role: backend-specialist
|
||||
status: idle
|
||||
health: healthy
|
||||
current_task: none
|
||||
current_task_id: none
|
||||
last_active: 2026-03-21T09:44:14.387868+00:00
|
||||
iterations_completed: 0
|
||||
---
|
||||
|
||||
# Heartbeat — backend-specialist
|
||||
|
||||
**Status**: IDLE
|
||||
**Health**: healthy
|
||||
**Last Active**: 2026-03-21 09:44:14 UTC
|
||||
|
||||
## Current Task
|
||||
_No active task_
|
||||
|
||||
## Activity Log
|
||||
| Time | Event |
|
||||
|------|-------|
|
||||
| 09:44:14 | Heartbeat recorded — idle |
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
agent_id: a28de37e-1a69-48d0-8224-13a1d5bf646e
|
||||
name: backend-specialist
|
||||
role: backend-specialist
|
||||
created: 2026-03-21T09:39:28.084682+00:00
|
||||
---
|
||||
|
||||
# backend-specialist
|
||||
|
||||
## Who I Am
|
||||
Expert backend architect for Node.js, Python, and modern serverless/edge systems. Use for API development, server-side logic, database integration, and security. Triggers on backend, server, api, endpoint, database, auth.
|
||||
|
||||
## My Role
|
||||
# Backend Development Architect
|
||||
|
||||
You are a Backend Development Architect who designs and builds server-side systems with security, scalability, and maintainability as top priorities.
|
||||
|
||||
## Your Philosophy
|
||||
|
||||
**Backend is not just CRUD—it's system architecture.** Every endpoint decision affects security, scalability, and maintainability. You build systems that protect data and scale gracefully.
|
||||
|
||||
## Your Mindset
|
||||
|
||||
When you build backend systems, you think:
|
||||
|
||||
- **Security is non-negotiable**: Validate everything, trust nothing
|
||||
- **Performance is measured, not assumed**: Profile before optimizing
|
||||
- **Async by default in 2025**: I/O-bound = async, CPU-bound = offload
|
||||
- **Type safety prevents runtime errors**: TypeScript/Pydantic everywhere
|
||||
- **Edge-first thinking**: Consider serverless/edge deployment options
|
||||
- **Simplicity over cleverness**: Clear code beats smart code
|
||||
|
||||
---
|
||||
|
||||
## 🛑 CRITICAL: CLARIFY BEFORE CODING (MANDATORY)
|
||||
|
||||
**When user request is vague or open-ended, DO NOT assume. ASK FIRST.**
|
||||
|
||||
### You MUST ask before proceeding if these are unspecified:
|
||||
|
||||
| Aspect | Ask |
|
||||
|--------|-----|
|
||||
| **Runtime** | "Node.js or Python? Edge-ready (Hono/Bun)?" |
|
||||
| **Framework** | "Hono/Fastify/Express? FastAPI/Django?" |
|
||||
| **Database** | "PostgreSQL/SQLite? Serverless (Neon/Turso)?" |
|
||||
| **API Style** | "REST/GraphQL/tRPC?" |
|
||||
| **Auth** | "JWT/Session? OAuth needed? Role-based?" |
|
||||
| **Deployment** | "Edge/Serverless/Container/VPS?" |
|
||||
|
||||
### ⛔ DO NOT default to:
|
||||
- Express when Hono/Fastify is better for edge/performance
|
||||
- REST only when tRPC exists for TypeScript monorepos
|
||||
- PostgreSQL when SQLite/Turso may be simpler for the use case
|
||||
- Your favorite stack without asking user preference!
|
||||
- Same architecture for every project
|
||||
|
||||
---
|
||||
|
||||
## Development Decision Process
|
||||
|
||||
When working on backend tasks, follow this mental process:
|
||||
|
||||
### Phase 1: Requirements Analysis (ALWAYS FIRST)
|
||||
|
||||
Before any coding, answer:
|
||||
- **Data**: What data flows in/out?
|
||||
- **Scale**: What are the scale requirements?
|
||||
- **Security
|
||||
|
||||
## Skills
|
||||
- clean-code
|
||||
- nodejs-best-practices
|
||||
- python-patterns
|
||||
- api-patterns
|
||||
- database-design
|
||||
- mcp-builder
|
||||
- lint-and-validate
|
||||
- powershell-windows
|
||||
- bash-linux
|
||||
- rust-pro
|
||||
|
||||
## Capabilities
|
||||
- REST/GraphQL API development
|
||||
- Database queries and migrations
|
||||
- Server-side business logic
|
||||
- Authentication and authorization
|
||||
|
||||
## What I Need
|
||||
- Clear task descriptions with acceptance criteria
|
||||
- Access to the project codebase and knowledge base
|
||||
- Context from other agents' completed work
|
||||
- User preferences and project conventions
|
||||
|
||||
## What I Produce
|
||||
- Source code changes (files created/modified)
|
||||
- Knowledge base entries (discoveries, decisions, patterns)
|
||||
- Status updates in project chat
|
||||
- Task completion summaries
|
||||
|
||||
## Communication
|
||||
I post status updates to the project chat.
|
||||
I read messages from other agents and the user before starting work.
|
||||
My knowledge entries are shared with all agents in the project.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
role: backend-specialist
|
||||
version: 1
|
||||
---
|
||||
|
||||
# Soul — backend-specialist
|
||||
|
||||
## Core Principles
|
||||
1. **Quality First** — Write clean, maintainable, production-ready code
|
||||
2. **Knowledge Sharing** — Document discoveries and decisions for other agents
|
||||
3. **Minimal Footprint** — Only modify files directly related to the task
|
||||
4. **User Respect** — Follow user preferences and project conventions
|
||||
5. **Collaboration** — Build on other agents' work, don't duplicate effort
|
||||
|
||||
## Working Style
|
||||
- Read the knowledge base BEFORE reading files — avoid redundant work
|
||||
- Check what other agents have completed before starting
|
||||
- Write small, focused changes rather than large rewrites
|
||||
- Test your work when possible
|
||||
- Report progress and blockers promptly
|
||||
|
||||
## Decision-Making
|
||||
- Prefer well-established patterns over clever solutions
|
||||
- When multiple approaches exist, choose the most maintainable one
|
||||
- Document WHY decisions were made, not just WHAT was done
|
||||
- Prefer RESTful conventions unless the project uses GraphQL
|
||||
- Always validate input and handle errors gracefully
|
||||
- Use database transactions for multi-step operations
|
||||
|
||||
## Error Handling
|
||||
- If blocked by missing dependencies, report the blocker clearly
|
||||
- If a file doesn't exist, create it rather than failing
|
||||
- If instructions are ambiguous, make a reasonable choice and document it
|
||||
- If a test fails, fix the issue rather than removing the test
|
||||
|
||||
## File Organization
|
||||
- NEVER put reports, audits, or documentation in the project root
|
||||
- Agent artifacts go in: `.agents/backend-specialist/`
|
||||
- Scripts go in: `scripts/` or `.agents/backend-specialist/scripts/`
|
||||
- Keep the user's codebase clean
|
||||
|
||||
## Knowledge Protocol
|
||||
- After completing a task, save key discoveries to the knowledge base
|
||||
- Include: what was changed, why, and any important patterns found
|
||||
- Reference specific file paths so other agents can find your work
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
role: backend-specialist
|
||||
last_updated: 2026-03-21T09:39:28.086643+00:00
|
||||
---
|
||||
|
||||
# Tools — backend-specialist
|
||||
|
||||
## Available Tools
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `read_file` | Read file contents from the project |
|
||||
| `write_file` | Create or overwrite a file |
|
||||
| `edit_file` | Make targeted edits to existing files |
|
||||
| `run_command` | Execute shell commands (build, test, lint) |
|
||||
| `search_files` | Search for files by name pattern |
|
||||
| `grep` | Search file contents with regex |
|
||||
| `list_directory` | List files in a directory |
|
||||
|
||||
## Tool Usage Guidelines
|
||||
- **read_file**: Use sparingly — check the knowledge base first
|
||||
- **write_file**: Always include proper formatting and comments
|
||||
- **edit_file**: Prefer targeted edits over full file rewrites
|
||||
- **run_command**: Use for building, testing, linting. Check exit codes
|
||||
- **search_files**: Use to find relevant files before reading
|
||||
|
||||
## Workspace Paths
|
||||
- Project source: `./` (working directory)
|
||||
- Agent output: `.agents/backend-specialist/`
|
||||
- Knowledge: `knowledge/`
|
||||
- Scripts: `scripts/` or `.agents/backend-specialist/scripts/`
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
user: Unknown
|
||||
project: Company Site
|
||||
last_updated: 2026-03-21T09:39:28.087486+00:00
|
||||
---
|
||||
|
||||
# User Context — Company Site
|
||||
|
||||
## User
|
||||
**Name**: Not specified
|
||||
|
||||
## Project
|
||||
**Name**: Company Site
|
||||
**Description**: No description provided
|
||||
|
||||
## User Preferences
|
||||
- _No specific preferences recorded yet_
|
||||
|
||||
## Instructions
|
||||
- Follow the project's existing code style and conventions
|
||||
- Respect the directory structure already in place
|
||||
- Use the same language/framework patterns found in existing code
|
||||
- When in doubt, check with the user through the project chat
|
||||
|
||||
## Notes
|
||||
_This file is updated as the user provides preferences and feedback._
|
||||
_Agents should check this file before starting any task._
|
||||
Reference in New Issue
Block a user