Skip to content

feat: log aggregation and retention#3

Open
devEunicee wants to merge 319 commits into
mainfrom
feat/299-log-aggregation
Open

feat: log aggregation and retention#3
devEunicee wants to merge 319 commits into
mainfrom
feat/299-log-aggregation

Conversation

@devEunicee
Copy link
Copy Markdown
Owner

Closes AnnabelJoe#299

Changes

  • Add structured logger with Logtail/Better Stack integration
  • Sensitive field sanitization (keys, signatures)
  • Next.js instrumentation hook for log initialization
  • LOGGING.md with retention policy (30d info, 90d errors) and alert setup
  • Add LOGTAIL_SOURCE_TOKEN to .env.example

AnnabelJoe and others added 30 commits April 23, 2026 22:37
…act-versioning

feat(contracts): add version tracking and migration support (AnnabelJoe#70)
…ng-env

feat(infra): set up staging environment on Vercel (AnnabelJoe#89)
docs(adr): add ADR template, index, and 4 ADRs (AnnabelJoe#99)
feat(backup): daily pg_dump to S3 with 30-day retention and Slack ale…
fix(ci): commit pnpm lockfile for frozen-lockfile enforcement (AnnabelJoe#86)
…itoring

feat(monitoring): add uptime checks for /api/health and /verify (AnnabelJoe#84)
)

- verify: add VerifyQuerySchema (Zod) for id query param (UUID or 64-char hex)
- verify: replace raw .or() interpolation with parameterised .eq() loop to eliminate injection risk
- retire: add ParamsSchema (Zod) to validate id path param as UUID before any business logic
)

- Add auth.cooperative_id() and auth.is_admin() JWT claim helpers
- Enable RLS on cooperatives, meters, readings, certificates
- Operators scoped to their own cooperative_id via JWT app_metadata claim
- readings scoped via parent meter's cooperative_id (no direct FK)
- Admin role bypasses all restrictions
- Migration 004: 5-assertion DO block tests cross-operator isolation
…nnabelJoe#61)

- Fix metadata: name 'SolarProof kWh', symbol 'SKWH'
- Add DataKey::Allowance(from, spender) storage key
- Implement approve(), allowance(), transfer_from(), burn_from()
- Extract move_balance/deduct_balance/add_burned/spend_allowance helpers
- Fix setup() to consistently return 2-tuple across all tests
- Add 8 SEP-41 compliance tests: metadata, approve, allowance,
  transfer_from, burn_from, overwrite, revoke, cross-operator guard
…age (AnnabelJoe#56)

Add 14 missing tests covering all functions and edge cases:
- initialize: double-init panics
- balance: zero for unknown account
- total_supply: zero before any mint
- mint: zero amount panics
- transfer: zero amount panics, no balance panics, self-transfer
- burn: zero amount panics, no balance panics
- approve: negative amount panics
- transfer_from: zero amount panics
- burn_from: zero amount panics
- set_minter: rotates minter correctly
- admin: returns correct address
…token-coverage

Test/issue 56 energy token coverage
- Add VoteLock key to DataKey enum
- Set lock at entry of vote(), clear on exit
- Panic with 'reentrant call' if lock already held
- State updates (bitmap + proposals) happen before lock release
- Add test_vote_reentrancy_rejected test

Closes AnnabelJoe#53
- Add ApiSigner key to DataKey enum
- initialize() now requires api_signer address alongside admin
- anchor() takes caller param; panics 'unauthorized' if caller != api_signer
- set_api_signer() allows admin to rotate the authorized signer
- Tests updated: unauthorized caller rejected, set_api_signer coverage

Closes AnnabelJoe#52
…l-anchor

fix(audit-registry): add access control to anchor() [AnnabelJoe#52]
…ard-vote

fix(governance): add reentrancy guard to vote() [AnnabelJoe#53]
- Add PendingUpgrade key and UpgradeProposal struct to DataKey
- propose_upgrade(): admin-only, stores wasm hash + unlock_ledger (now + 17280 ledgers ≈ 48h)
- cancel_upgrade(): admin-only, removes pending proposal within window
- execute_upgrade(): admin-only, calls update_current_contract_wasm after timelock
- pending_upgrade() getter
- Events emitted: upg_prop, upg_cncl, upg_exec
- Tests: proposal stored, duplicate rejected, cancel works, execute before timelock panics

Closes AnnabelJoe#55
- not-found.tsx: branded 404 with Sun icon and link back to /dashboard
- error.tsx: branded 500 with error reference ID (error.digest fallback),
  Try again reset button, and link back to /dashboard
- Both pages use existing Tailwind classes and are accessible/responsive

Closes AnnabelJoe#22
…-pages

feat(web): add custom 404 and 500 error pages [AnnabelJoe#22]
…lock

feat(governance): add contract upgrade mechanism with 48h timelock [AnnabelJoe#55]
…lication-integration-test

Add audit registry deduplication + local Soroban integration tests
- Add pnpm test step between type-check and build
- Cache apps/web/.next/cache keyed on source files + lockfile
- Add TURBO_TOKEN/TURBO_TEAM env to build step

Closes AnnabelJoe#76
… support

- Add src/lib/secrets.ts: getMinterKeypair() and getValidMinterKeypairs()
- Previous key stays valid for 24 h after rotation (grace window)
- Every key load is written to the Supabase audit_log table
- stellar.ts updated to call getMinterKeypair() instead of reading env directly
- env.ts: MINTER_SECRET_ARN (required in prod), MINTER_PREVIOUS_SECRET_ARN (grace window), MINTER_SECRET_KEY (local dev fallback)
- .env.example updated with new vars
- Add @aws-sdk/client-secrets-manager dependency

Closes AnnabelJoe#50
- Add src/lib/logger.ts: structured JSON logger that ships to Logtail
  in production and falls back to stdout locally
- env.ts: add optional LOGTAIL_SOURCE_TOKEN server var
- .env.example: document LOGTAIL_SOURCE_TOKEN
- docs/LOGGING.md: setup guide, log format, alert configuration

Closes AnnabelJoe#92
- .github/workflows/branch-protection.yml: applies protection rules via
  GitHub API on push to main (or manual trigger)
- Rules: 1 required approval, stale review dismissal, CI must pass,
  no force pushes, no deletions, conversation resolution required
- enforce_admins: true on main, false on develop
- docs/BRANCH_PROTECTION.md: setup guide and rule reference

Closes AnnabelJoe#81
- Accept up to 100 signed meter readings in a single request
- Validate and anchor each reading independently in parallel
- Return per-reading status with partial success (HTTP 207)
- Bulk-fetch meters in one DB query for efficiency

Also fixes pre-existing CI failures:
- Add eslint.config.mjs (ESLint was unconfigured)
- Fix SorobanRpc import (renamed to Soroban.rpc in stellar-sdk v13)
- Fix Sentry hideSourceMaps -> sourcemaps.disable (v9 API)
- Fix database.types.ts to satisfy GenericSchema (add Relationships)
- Fix verify() -> verifyAsync() (@noble/ed25519 v3 sync API change)
- Add missing @noble/ed25519 and @eslint/eslintrc deps
PrincessnJoy and others added 24 commits May 29, 2026 02:40
- Add .github/workflows/blue-green-deploy.yml: deploy preview → health checks (5x) → promote to production
- Add docs/runbook/blue-green-deployment.md: step-by-step runbook with rollback instructions
- Health checks run against preview URL before any traffic shift
- Instant rollback via vercel promote <previous-url>

Closes AnnabelJoe#301
…-deployment

devops(deploy): add blue-green deployment strategy for zero-downtime releases
…g-checks

ci(lint): add Prettier formatting check to CI and pre-commit hooks
…lth-checks

devops(docker): add health checks for all services
…ction

fix: implement CSRF protection for state-changing API endpoints
## [1.7.1](AnnabelJoe/solarproof@v1.7.0...v1.7.1) (2026-05-29)

### Bug Fixes

* implement CSRF protection for state-changing API endpoints ([AnnabelJoe#335](AnnabelJoe#335)) ([2c6c8c8](AnnabelJoe@2c6c8c8))
…sions

docs(adr): add ADR-005 monorepo structure and ADR-006 certificate retirement model
…automation

feat: automate Stellar Testnet faucet funding in CI
## [1.8.0](AnnabelJoe/solarproof@v1.7.1...v1.8.0) (2026-05-29)

### Features

* automate Stellar Testnet faucet funding in CI ([AnnabelJoe#303](AnnabelJoe#303)) ([25598db](AnnabelJoe@25598db))

### Documentation

* **adr:** add ADR-005 monorepo structure and ADR-006 certificate retirement model ([d7c679a](AnnabelJoe@d7c679a)), closes [AnnabelJoe#311](AnnabelJoe#311)
…ack-protection

fix: add replay attack protection to audit_registry contract
## [1.8.1](AnnabelJoe/solarproof@v1.8.0...v1.8.1) (2026-05-29)

### Bug Fixes

* add replay attack protection to audit_registry contract ([AnnabelJoe#280](AnnabelJoe#280)) ([b4e10b7](AnnabelJoe@b4e10b7))
…erflow-audit

fix: use checked arithmetic in energy_token to prevent integer overflow
## [1.8.2](AnnabelJoe/solarproof@v1.8.1...v1.8.2) (2026-05-29)

### Bug Fixes

* use checked arithmetic in energy_token to prevent overflow ([AnnabelJoe#277](AnnabelJoe#277)) ([f526e26](AnnabelJoe@f526e26))
…-smoke-governance-tests

Add contract docs, backup recovery guide, smoke test, and governance tests
@github-actions
Copy link
Copy Markdown

✅ pnpm audit

4 vulnerabilities found
Severity: 4 moderate

@github-actions
Copy link
Copy Markdown

🔍 Vercel Preview Deployment

URL: Learn More: https://err.sh/vercel/no-credentials-found

Uses Stellar testnet contract addresses.

Comment thread apps/web/e2e/a11y.spec.ts
* violations are found. Baseline violations (if any) are documented below.
*/

import { test, expect } from '@playwright/test'

const METER_ID = '123e4567-e89b-12d3-a456-426614174000'
const KWH = 12.5
const TIMESTAMP = 1_700_000_000
/** Build a Supabase mock that returns the given meter row. */
function mockDb(meter: unknown) {
const single = vi.fn().mockResolvedValue({ data: meter, error: null })
const eq = vi.fn().mockReturnValue({ single })
Comment on lines +3 to +12
import {
Zap,
ShieldCheck,
Link2,
Award,
FlameKindling,
ExternalLink,
CheckCircle2,
Clock,
} from 'lucide-react'

export function Navbar() {
const pathname = usePathname()
const { resolvedTheme, setTheme } = useTheme()
}

/** Delays that grow as 1 s, 2 s, 4 s for attempts 1, 2, 3. */
const BACKOFF_MS = [1_000, 2_000, 4_000]

/** Delays that grow as 1 s, 2 s, 4 s for attempts 1, 2, 3. */
const BACKOFF_MS = [1_000, 2_000, 4_000]
const MAX_RETRIES = 3
const inMock = vi.fn().mockReturnValue({ error: null })
deleteMock.mockReturnValue({ in: inMock })

function makeInsertMock(row: Record<string, unknown>) {

#[test]
fn test_api_signer_query() {
let (env, api_signer, client) = setup();
@github-actions
Copy link
Copy Markdown

✅ cargo audit

�[1m�[32m    Updating�[0m crates.io index
�[1m�[32m     Locking�[0m 188 packages to latest compatible versions
�[1m�[36m      Adding�[0m arbitrary v1.3.2 �[1m�[33m(available: v1.4.2)�[0m
�[1m�[36m      Adding�[0m crypto-common v0.1.6 �[1m�[33m(available: v0.1.7)�[0m
�[1m�[36m      Adding�[0m derive_arbitrary v1.3.2 �[1m�[33m(available: v1.4.2)�[0m
�[1m�[36m      Adding�[0m soroban-builtin-sdk-macros v23.0.1 �[1m�[33m(available: v23.0.2)�[0m
�[1m�[36m      Adding�[0m soroban-env-common v23.0.1 �[1m�[33m(available: v23.0.2)�[0m
�[1m�[36m      Adding�[0m soroban-env-guest v23.0.1 �[1m�[33m(available: v23.0.2)�[0m
�[1m�[36m      Adding�[0m soroban-env-host v23.0.1 �[1m�[33m(available: v23.0.2)�[0m
�[1m�[36m      Adding�[0m soroban-env-macros v23.0.1 �[1m�[33m(available: v23.0.2)�[0m
�[1m�[36m      Adding�[0m soroban-sdk v23.5.3 �[1m�[33m(available: v25.3.0)�[0m
�[0m�[0m�[1m�[32m    Fetching�[0m advisory database from `https://github.com/RustSec/advisory-db.git`
�[0m�[0m�[1m�[32m      Loaded�[0m 1098 security advisories (from /home/runner/.cargo/advisory-db)
�[0m�[0m�[1m�[32m    Updating�[0m crates.io index
�[0m�[0m�[1m�[32m    Scanning�[0m Cargo.lock for vulnerabilities (192 crate dependencies)
�[0m�[0m�[1m�[33mCrate:    �[0m derivative
�[0m�[0m�[1m�[33mVersion:  �[0m 2.2.0
�[0m�[0m�[1m�[33mWarning:  �[0m unmaintained
�[0m�[0m�[1m�[33mTitle:    �[0m `derivative` is unmaintained; consider using an alternative
�[0m�[0m�[1m�[33mDate:     �[0m 2024-06-26
�[0m�[0m�[1m�[33mID:       �[0m RUSTSEC-2024-0388
�[0m�[0m�[1m�[33mURL:      �[0m https://rustsec.org/advisories/RUSTSEC-2024-0388
�[0m�[0m�[1m�[33mDependency tree:
�[0mderivative 2.2.0
├── ark-poly 0.4.2
│   └── ark-ec 0.4.2
│       ├── soroban-env-host 23.0.1
│       │   ├── soroban-sdk 23.5.3
│       │   │   ├── multisig-admin 1.0.0
│       │   │   ├── energy-token 1.0.0
│       │   │   ├── community-governance 1.0.0
│       │   │   └── audit-registry 1.0.0
│       │   └── soroban-ledger-snapshot 23.5.3
│       │       └── soroban-sdk 23.5.3
│       └── ark-bls12-381 0.4.0
│           └── soroban-env-host 23.0.1
├── ark-ff 0.4.2
│   ├── soroban-env-host 23.0.1
│   ├── ark-poly 0.4.2
│   ├── ark-ec 0.4.2
│   └── ark-bls12-381 0.4.0
└── ark-ec 0.4.2

�[0m�[0m�[1m�[33mCrate:    �[0m paste
�[0m�[0m�[1m�[33mVersion:  �[0m 1.0.15
�[0m�[0m�[1m�[33mWarning:  �[0m unmaintained
�[0m�[0m�[1m�[33mTitle:    �[0m paste - no longer maintained
�[0m�[0m�[1m�[33mDate:     �[0m 2024-10-07
�[0m�[0m�[1m�[33mID:       �[0m RUSTSEC-2024-0436
�[0m�[0m�[1m�[33mURL:      �[0m https://rustsec.org/advisories/RUSTSEC-2024-0436
�[0m�[0m�[1m�[33mDependency tree:
�[0mpaste 1.0.15
├── wasmi_core 0.13.0
│   └── soroban-wasmi 0.31.1-soroban.20.0.1
│       ├── soroban-env-host 23.0.1
│       │   ├── soroban-sdk 23.5.3
│       │   │   ├── multisig-admin 1.0.0
│       │   │   ├── energy-token 1.0.0
│       │   │   ├── community-governance 1.0.0
│       │   │   └── audit-registry 1.0.0
│       │   └── soroban-ledger-snapshot 23.5.3
│       │       └── soroban-sdk 23.5.3
│       └── soroban-env-common 23.0.1
│           ├── soroban-sdk-macros 23.5.3
│           │   └── soroban-sdk 23.5.3
│           ├── soroban-ledger-snapshot 23.5.3
│           ├── soroban-env-host 23.0.1
│           └── soroban-env-guest 23.0.1
│               └── soroban-sdk 23.5.3
└── ark-ff 0.4.2
    ├── soroban-env-host 23.0.1
    ├── ark-poly 0.4.2
    │   └── ark-ec 0.4.2
    │       ├── soroban-env-host 23.0.1
    │       └── ark-bls12-381 0.4.0
    │           └── soroban-env-host 23.0.1
    ├── ark-ec 0.4.2
    └── ark-bls12-381 0.4.0

�[0m�[0m�[1m�[33mwarning:�[0m 2 allowed warnings found

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configure log aggregation and retention for production