Salta ai contenuti

Observatory Specs

Questi contenuti non sono ancora disponibili nella tua lingua.

🛠️ Rhama Observatory - Technical Specifications

Section titled “🛠️ Rhama Observatory - Technical Specifications”

Technical Reference - Complete architecture, API schemas, and implementation details for the Rhama Observatory.


A Rhama is a poetic gift generated by the IN-1 AI after a meaningful conversation. It typically consists of 3-4 lines of nature-inspired imagery that reflects the user’s emotional state.

Example:

Under snow, roots wait—
spring hides inside every seed
the forest trusts time

Table: in1.rhamas
Provider: Neon PostgreSQL 17
Connection: SSL-encrypted pooled connection

Columns:

CREATE TABLE in1.rhamas (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES auth.users(id),
session_id VARCHAR(255),
prompt_text TEXT NOT NULL,
haiku_text TEXT NOT NULL,
emotion VARCHAR(50),
tree_planted BOOLEAN DEFAULT FALSE,
tree_id VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Indexes:

  • idx_rhamas_user on user_id
  • idx_rhamas_session on session_id
  • idx_rhamas_created on created_at DESC

URL: GET /api/observatory/stats.json

Purpose: Returns global statistics and heatmap data for the calendar view.

Response Schema:

interface StatsResponse {
success: boolean;
data: {
total: number;
heatmap: Array<{
date: string; // Format: YYYY-MM-DD
count: number; // Number of Rhamas generated that day
}>;
};
}

Example Response:

{
"success": true,
"data": {
"total": 1523,
"heatmap": [
{ "date": "2024-12-21", "count": 12 },
{ "date": "2024-12-20", "count": 8 },
{ "date": "2024-12-19", "count": 5 }
]
}
}

Cache: 5 minutes (300 seconds)

SQL Query:

-- Total count
SELECT COUNT(*) as total FROM in1.rhamas;
-- Heatmap (last 365 days)
SELECT
DATE(created_at) as date,
COUNT(*) as count
FROM in1.rhamas
WHERE created_at >= CURRENT_DATE - INTERVAL '365 days'
GROUP BY DATE(created_at)
ORDER BY date DESC;

URL: GET /api/observatory/day/[YYYY-MM-DD].json

Purpose: Returns all Rhamas generated on a specific date.

Parameters:

  • date (path parameter): Date in YYYY-MM-DD format

Response Schema:

interface DayResponse {
success: boolean;
data: {
date: string;
count: number;
rhamas: Array<{
id: number;
text: string;
prompt: string; // Truncated to 100 chars
emotion: string | null;
createdAt: string; // ISO 8601 format
treePlanted: boolean;
isAnonymous: boolean;
}>;
};
}

Example Response:

{
"success": true,
"data": {
"date": "2024-12-21",
"count": 12,
"rhamas": [
{
"id": 456,
"text": "Snow falls, no sound...",
"prompt": "User was reflecting on winter solitude...",
"emotion": "serenity",
"createdAt": "2024-12-21T14:32:15Z",
"treePlanted": true,
"isAnonymous": false
}
]
}
}

Cache: 1 minute (60 seconds)

SQL Query:

SELECT
id,
haiku_text,
prompt_text,
emotion,
created_at,
tree_planted,
user_id
FROM in1.rhamas
WHERE DATE(created_at) = $1
ORDER BY created_at DESC;

LayerTechnologyPurpose
FrontendReact 19 (TSX)Interactive UI components
FrameworkAstro 5 (Hybrid mode)Static docs + SSR API
DatabasePostgreSQL 17 (Neon)Serverless Postgres
Clientpg (node-postgres)Database connection pooling
Date Utilsdate-fnsDate formatting & manipulation
IconsLucide ReactIcon system
StylingTailwind CSSUtility-first CSS
DesignDark Forest GlassmorphismCustom theme system
BLACKTRAILS-DOCS/
├── src/
│ ├── pages/api/observatory/
│ │ ├── stats.json.ts # SSR endpoint (prerender: false)
│ │ └── day/[date].json.ts # Dynamic SSR endpoint
│ ├── components/observatory/
│ │ └── RhamaHeatmap.tsx # React calendar component
│ └── content/docs/private/brands/in1/
│ ├── observatory.mdx # Dashboard page
│ └── observatory-technical.md # This file
├── astro.config.mjs # Hybrid mode + Node adapter
└── .env # DATABASE_URL (gitignored)
sequenceDiagram
    participant User
    participant Browser
    participant Astro
    participant API
    participant Neon

    User->>Browser: Navigate to Observatory
    Browser->>Astro: Request /private/brands/in1/observatory
    Astro->>Browser: Return HTML + React component
    Browser->>API: Fetch /api/observatory/stats.json
    API->>Neon: Query: COUNT + Heatmap
    Neon-->>API: Return aggregated data
    API-->>Browser: JSON response (cached 5min)
    Browser->>User: Render calendar with data
    
    User->>Browser: Click on day
    Browser->>API: Fetch /api/observatory/day/2024-12-21.json
    API->>Neon: Query: SELECT WHERE date = ?
    Neon-->>API: Return Rhamas for that day
    API-->>Browser: JSON response (cached 1min)
    Browser->>User: Display Rhama stream

  • No Personal Data Displayed: User IDs are never exposed in API responses
  • Context Truncated: Conversation prompts limited to 100 characters
  • Anonymous Tracking: Only timestamps and text content visible
  • Secure Connection: All queries use SSL (sslmode=require)
  • Connection Pooling: Prevents connection exhaustion attacks
Terminal window
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require

Security Notes:

  • ✅ Stored in .env (gitignored)
  • ✅ Never committed to version control
  • ✅ Injected at build/runtime via Astro env system
  • ✅ SSL certificate validation enabled

Use this dashboard to:

  1. Identify Peak Activity: Which days/weeks see the most Rhama generation?
  2. Monitor Growth: Is the platform usage increasing over time?
  3. Quality Assurance: Spot check Rhama quality across different time periods
  4. Emotion Distribution: Which emotions are most commonly detected?
  5. Tree Planting Impact: How many Rhamas result in real tree planting?
MetricQueryPurpose
Total GeneratedCOUNT(*)Lifetime platform usage
Daily AverageCOUNT(*) / days_activeSustained engagement
Peak DayMAX(count) per dayViral moments
Tree Planting RateCOUNT(tree_planted = true) / COUNT(*)Environmental impact
Emotion DistributionGROUP BY emotionUser sentiment analysis

  • Emotion Breakdown: Pie chart of emotion distribution
  • Weekly/Monthly Aggregates: Time-series analysis beyond daily
  • Language Detection: Italian vs. English Rhama ratio
  • Export Functionality: Download CSV of all Rhamas
  • Search & Filter: Full-text search on Rhama content
  • Real-Time WebSocket: Live updates as new Rhamas are generated
  • User Journey: Anonymous tracking of conversation→Rhama flow
  • Performance Metrics: API response times, cache hit rates
  • Add Redis cache layer for stats endpoint
  • Implement rate limiting on API endpoints
  • Add OpenTelemetry instrumentation
  • Create Playwright E2E tests
  • Document error handling strategy

  1. Start Dev Server:

    Terminal window
    cd E:\BLACKTRAILS-DOCS
    npm run dev
  2. Access Dashboard:

    http://localhost:4321/private/brands/in1/observatory
  3. Test API Endpoints:

    Terminal window
    # Stats
    curl http://localhost:4321/api/observatory/stats.json
    # Daily details
    curl http://localhost:4321/api/observatory/day/2024-12-21.json
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
});
const result = await pool.query('SELECT COUNT(*) FROM in1.rhamas');
console.log('Total Rhamas:', result.rows[0].count);
await pool.end();


Last Updated: December 21, 2025
Data Source: in1.rhamas (Neon PostgreSQL)
Maintainer: BlackTrails AI Team
Version: 1.0.0