@andamio/db-api
v0.5.2
Published
Type-safe database API client for Andamio Platform - TypeScript types, Zod schemas, and API utilities for building Cardano learning applications
Readme
@andamio-platform/db-api
Type-safe database API client for Andamio Platform - TypeScript types, Zod schemas, and API utilities for building Cardano learning applications.
Installation
npm install @andamio-platform/db-apiOverview
This package provides TypeScript types and Zod schemas for the Andamio Database API. Import types to get full type safety and autocomplete when working with the Andamio API, with zero framework dependencies required.
Key Features:
- ✅ Zero tRPC knowledge required - Clean TypeScript types
- ✅ Works with any HTTP client - fetch, axios, or any other client
- ✅ Full autocomplete and type safety - IntelliSense support
- ✅ Runtime validation - Optional Zod schemas for validation
- ✅ Versioned API support - Supports v0 (unstable) API endpoints
Quick Start
Basic Usage with Fetch
import {
type ListOwnedCoursesOutput,
type CourseOutput,
type CreateCourseInput
} from "@andamio-platform/db-api";
// GET request with typed response
const response = await fetch(`${API_URL}/courses/owned`, {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
const courses = (await response.json()) as ListOwnedCoursesOutput;
// POST request with typed input and output
const createData: CreateCourseInput = {
courseCode: "CS101",
courseName: "Introduction to Computer Science",
// ... other fields
};
const createResponse = await fetch(`${API_URL}/courses`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify(createData),
});
const newCourse = (await createResponse.json()) as CourseOutput;Runtime Validation with Schemas
import {
type ListOwnedCoursesOutput,
listOwnedCoursesOutputSchema
} from "@andamio-platform/db-api";
const response = await fetch(`${API_URL}/courses/owned`);
const data = await response.json();
// Runtime validation with Zod
const courses = listOwnedCoursesOutputSchema.parse(data);
// TypeScript now knows courses is ListOwnedCoursesOutputPackage Exports
This package provides multiple export paths for different use cases:
Default Export (Recommended)
// Import types and schemas (no tRPC dependency)
import {
type CourseOutput,
type CreateCourseInput,
courseOutputSchema
} from "@andamio-platform/db-api";Explicit Imports
// Schemas and types
import { type CourseOutput } from "@andamio-platform/db-api/schemas";
// tRPC-inferred types (legacy)
import { type RouterInputs, type RouterOutputs } from "@andamio-platform/db-api/types";Available Types
The package exports types for all API endpoints, organized by domain:
Course Types
import {
type CourseOutput,
type ListOwnedCoursesOutput,
type ListPublishedCoursesOutput,
type CreateCourseInput,
type UpdateCourseInput,
type DeleteCourseInput,
// ... and schemas
courseOutputSchema,
listOwnedCoursesOutputSchema,
} from "@andamio-platform/db-api";Course Module Types
import {
type CourseModuleOutput,
type ListCourseModulesOutput,
type CreateCourseModuleInput,
type UpdateCourseModuleInput,
// ... and schemas
} from "@andamio-platform/db-api";Lesson Types
import {
type LessonOutput,
type ListLessonsOutput,
type CreateLessonInput,
type UpdateLessonInput,
// ... and schemas
} from "@andamio-platform/db-api";Assignment Types
import {
type AssignmentOutput,
type CreateAssignmentInput,
type UpdateAssignmentInput,
type PublishAssignmentInput,
// ... and schemas
} from "@andamio-platform/db-api";Assignment Commitment Types
import {
type AssignmentCommitmentOutput,
type AssignmentCommitmentWithAssignmentOutput,
type CreateAssignmentCommitmentInput,
type UpdateAssignmentCommitmentEvidenceInput,
type UpdateAssignmentCommitmentStatusInput,
type DeleteAssignmentCommitmentInput,
type PrivateStatus,
type NetworkStatus,
// ... and schemas
assignmentCommitmentOutputSchema,
networkStatusSchema,
privateStatusSchema,
} from "@andamio-platform/db-api";Pending Transaction Types
import {
type PendingTransaction,
type ListPendingTransactionsOutput,
// ... and schemas
listPendingTransactionsOutputSchema,
} from "@andamio-platform/db-api";SLT (Student Learning Target) Types
import {
type SLTOutput,
type ListSLTsOutput,
type CreateSLTInput,
type UpdateSLTInput,
// ... and schemas
} from "@andamio-platform/db-api";Auth Types
import {
type CreateSessionInput,
type CreateSessionOutput,
type ValidateSignatureInput,
type ValidateSignatureOutput,
// ... and schemas
} from "@andamio-platform/db-api";Learner Types
import {
type CreateLearnerInput,
type CreateLearnerOutput,
type GetMyLearningInput,
type GetMyLearningOutput,
// ... and schemas
} from "@andamio-platform/db-api";Contributor Types
import {
type CreateContributorInput,
type CreateContributorOutput,
type GetContributorCommitmentsInput,
type GetContributorCommitmentsOutput,
type GetTaskCommitmentByTaskHashInput,
type GetTaskCommitmentByTaskHashOutput,
type TaskCommitmentStatus,
type ListOnChainContributorPrerequisitesInput,
type ListOnChainContributorPrerequisitesOutput,
type ContributorPrerequisiteOutput,
// ... and schemas
taskCommitmentStatusSchema,
taskCommitmentOutputSchema,
taskInfoSchema,
tokenInfoSchema,
listOnChainContributorPrerequisitesInputSchema,
listOnChainContributorPrerequisitesOutputSchema,
contributorPrerequisiteOutputSchema,
} from "@andamio-platform/db-api";Treasury Types
import {
type TreasuryOutput,
type ListPublishedTreasuriesOutput,
type GetPublishedTreasuriesInput,
// ... and schemas
treasuryOutputSchema,
treasuryWithEscrowsOutputSchema,
listPublishedTreasuriesOutputSchema,
} from "@andamio-platform/db-api";Complete Type Reference
For a complete list of all available types and schemas, see API-TYPE-REFERENCE.md.
API Versioning
Current Version: 0.1.0 (Unstable)
This package supports the Andamio Database API v0, which is currently unstable and under active development.
⚠️ Version 0.x Status:
- Unstable - Breaking changes may occur between minor versions
- Use for development and testing only
- Not recommended for production
- Will be stabilized as v1.0.0 once API design is finalized
API Endpoints:
/api/v0/*- REST endpoints (recommended)/trpc/v0/*- tRPC endpoints
Examples
Fetching Published Courses
import { type ListPublishedCoursesOutput } from "@andamio-platform/db-api";
async function getPublishedCourses() {
const response = await fetch(`${API_URL}/courses/published`);
const courses = (await response.json()) as ListPublishedCoursesOutput;
courses.forEach(course => {
console.log(course.courseName, course.courseNftPolicyId);
});
}Creating a Course Module
import {
type CreateCourseModuleInput,
type CourseModuleOutput
} from "@andamio-platform/db-api";
async function createModule(
courseNftPolicyId: string,
moduleData: Omit<CreateCourseModuleInput, "courseNftPolicyId">
) {
const input: CreateCourseModuleInput = {
courseNftPolicyId,
...moduleData,
};
const response = await fetch(`${API_URL}/course-modules`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify(input),
});
return (await response.json()) as CourseModuleOutput;
}Updating a Lesson
import {
type UpdateLessonInput,
type LessonOutput
} from "@andamio-platform/db-api";
async function updateLesson(lessonData: UpdateLessonInput) {
const response = await fetch(`${API_URL}/lessons`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify(lessonData),
});
return (await response.json()) as LessonOutput;
}Getting Learner's Enrolled Courses (My Learning)
import { type GetMyLearningOutput } from "@andamio-platform/db-api";
async function getMyLearning() {
// Fetches courses the authenticated user is enrolled in
// based on on-chain data (course tokens in wallet)
const response = await fetch(`${API_URL}/learner/my-learning`, {
headers: { Authorization: `Bearer ${jwtToken}` },
});
const data = (await response.json()) as GetMyLearningOutput;
data.courses.forEach(course => {
console.log(`${course.title} - ${course.completedCount} assignments completed`);
});
return data.courses;
}Note: This endpoint queries on-chain enrollment data via the Andamio NBA (Node Backend API) to determine which courses the user is enrolled in, then fetches course details from the database. Enrollment is determined by checking for course tokens in the user's wallet.
Fetching Contributor Task Commitments
import { type GetContributorCommitmentsOutput } from "@andamio-platform/db-api";
async function getMyCommitments() {
// Fetches all task commitments for the authenticated contributor
// based on on-chain data from NBA API
const response = await fetch(`${API_URL}/contributor/commitments`, {
headers: { Authorization: `Bearer ${jwtToken}` },
});
const commitments = (await response.json()) as GetContributorCommitmentsOutput;
commitments.forEach(commitment => {
console.log(`Task: ${commitment.task.title}`);
console.log(`Status: ${commitment.status}`);
console.log(`Reward: ${commitment.task.lovelace} lovelace`);
});
}Fetching On-Chain Contributor Prerequisites
import { type ListOnChainContributorPrerequisitesOutput } from "@andamio-platform/db-api";
async function getContributorPrerequisites(treasuryNftPolicyId?: string) {
// Fetches all on-chain prerequisites
// Optionally filtered by treasury_nft_policy_id as a query parameter
const url = new URL(`${API_URL}/prerequisites/list-on-chain`);
if (treasuryNftPolicyId) {
url.searchParams.append("treasury_nft_policy_id", treasuryNftPolicyId);
}
const response = await fetch(url.toString());
const data = (await response.json()) as ListOnChainContributorPrerequisitesOutput;
data.contributor_prerequisites.forEach(prereq => {
console.log(`${prereq.title} - Policy: ${prereq.contributor_policy_id}`);
console.log(`Status: ${prereq.status}`);
});
}Fetching Published Treasuries (Projects)
import { type ListPublishedTreasuriesOutput } from "@andamio-platform/db-api";
async function getPublishedTreasuries(treasuryNftPolicyId?: string) {
// Fetches all published projects
// Optionally filtered by treasury_nft_policy_id as a query parameter
const url = new URL(`${API_URL}/projects`);
if (treasuryNftPolicyId) {
url.searchParams.append("treasury_nft_policy_id", treasuryNftPolicyId);
}
const response = await fetch(url.toString());
const treasuries = (await response.json()) as ListPublishedTreasuriesOutput;
treasuries.forEach(treasury => {
console.log(`${treasury.title} - ${treasury.total_ada} ADA total`);
console.log(`Escrows: ${treasury._count.escrows}`);
console.log(`Contributor Policy IDs: ${treasury.contributor_policy_ids.join(", ")}`);
});
}Checking Pending Transactions
import { type ListPendingTransactionsOutput } from "@andamio-platform/db-api";
async function getPendingTransactions() {
const response = await fetch(`${API_URL}/pending-transactions`, {
headers: { Authorization: `Bearer ${jwtToken}` },
});
const pendingTxs = (await response.json()) as ListPendingTransactionsOutput;
pendingTxs.forEach(tx => {
console.log(`${tx.entityType} - ${tx.txHash} (submitted: ${tx.submittedAt})`);
});
}Updating Assignment Commitment Status
import {
type UpdateAssignmentCommitmentStatusInput,
type AssignmentCommitmentOutput
} from "@andamio-platform/db-api";
async function updateCommitmentStatus(
courseNftPolicyId: string,
moduleCode: string,
accessTokenAlias: string,
newStatus: "PENDING_APPROVAL" | "AWAITING_EVIDENCE"
) {
const input: UpdateAssignmentCommitmentStatusInput = {
courseNftPolicyId,
moduleCode,
accessTokenAlias,
networkStatus: newStatus,
};
const response = await fetch(
`${API_URL}/assignment-commitments/${courseNftPolicyId}/${moduleCode}/${accessTokenAlias}/status`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify(input),
}
);
return (await response.json()) as AssignmentCommitmentOutput;
}Confirming Blockchain Transactions
import { type CourseModuleOutput } from "@andamio-platform/db-api";
async function confirmModuleTransaction(
courseNftPolicyId: string,
moduleCode: string,
txHash: string,
moduleHash?: string
) {
const response = await fetch(
`${API_URL}/course-modules/${courseNftPolicyId}/${moduleCode}/confirm-transaction`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify({
courseNftPolicyId,
moduleCode,
txHash,
moduleHash,
}),
}
);
return (await response.json()) as CourseModuleOutput;
}Creating a Task (Project Manager)
import {
type CreateTaskInput,
type CreateTaskOutput
} from "@andamio-platform/db-api";
async function createTask(
treasuryNftPolicyId: string,
taskData: Omit<CreateTaskInput, "treasuryNftPolicyId">
) {
const input: CreateTaskInput = {
treasuryNftPolicyId,
title: "Implement Feature X",
description: "Build the new dashboard feature with tests",
lovelace: "5000000", // 5 ADA reward
expirationTime: "1735689600000", // POSIX timestamp
acceptanceCriteria: [
"All tests pass",
"Code reviewed and approved",
"Documentation updated"
],
numAllowedCommitments: 1,
// Optional: Add native token rewards
tokens: [
{
policyId: "abc123...",
assetName: "546f6b656e", // hex-encoded
quantity: 100
}
]
};
const response = await fetch(
`${API_URL}/manager/projects/${treasuryNftPolicyId}/tasks`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`,
},
body: JSON.stringify(input),
}
);
return (await response.json()) as CreateTaskOutput;
}Note: This endpoint requires Project Manager role verified via NBA (Node Backend API). The system:
- Queries on-chain manager credentials from the blockchain
- Verifies the user manages the specified treasury
- Creates the task in DRAFT status in the treasury's first escrow
- Returns the created task with index, status, and optional token rewards
Using with React
Here's an example of using the types in a React component:
import { useState, useEffect } from "react";
import { type ListOwnedCoursesOutput } from "@andamio-platform/db-api";
function MyCourses() {
const [courses, setCourses] = useState<ListOwnedCoursesOutput>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchCourses() {
const response = await fetch(`${API_URL}/courses/owned`, {
headers: { Authorization: `Bearer ${jwtToken}` },
});
const data = (await response.json()) as ListOwnedCoursesOutput;
setCourses(data);
setLoading(false);
}
fetchCourses();
}, []);
if (loading) return <div>Loading...</div>;
return (
<ul>
{courses.map((course) => (
<li key={course.courseNftPolicyId}>{course.courseName}</li>
))}
</ul>
);
}Architecture
This package is designed to work with the Andamio Platform architecture:
Your Application
↓ (uses types from)
@andamio-platform/db-api (this package)
↓ (HTTP requests to)
Andamio API Gateway
↓ (routes to)
Andamio Database API
↓ (queries)
PostgreSQL DatabaseAPI Design Principles
- On-Chain Identifiers Only: The API uses blockchain identifiers (
courseNftPolicyId,courseCode,moduleCode) and never exposes internal database IDs - Role-Based Authorization: Supports Learner, Creator, Contributor, Treasury Owner, and Contribution Manager roles
- Type Safety: All inputs and outputs are fully typed with TypeScript
- Runtime Validation: Optional Zod schemas for runtime type checking
Development Setup
If you're contributing to this package or running it locally:
- Clone the repository
- Install dependencies:
npm install - Generate Prisma client:
npm run prisma:generate - Build:
npm run build - Run tests:
npm run test:api
See README-SERVER.md for complete server setup and deployment instructions.
Documentation
- API Type Reference - Complete type reference
- API Design Principles - Design philosophy and security
- Hash Handling Guide - Database hash storage, validation, and API patterns
- Server Setup - Running the database API server
- Publishing Guide - How to publish to npm (manual & automated)
- CI/CD Setup - Automated testing and publishing
Links
- npm: https://www.npmjs.com/package/@andamio-platform/db-api
- GitHub Repository: https://github.com/Andamio-Platform/andamio-platform-monorepo/tree/main/andamio-db-api
- Report Issues: https://github.com/Andamio-Platform/andamio-platform-monorepo/issues
- Andamio Platform: https://andamio.io
License
MIT © Andamio
