turash/bugulma/frontend/BACKEND_ALIGNMENT.md
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

181 lines
5.6 KiB
Markdown

# Frontend-Backend Alignment
This document describes the alignment between the frontend and the enhanced Go backend.
## Architecture Overview
The frontend now communicates with the backend through:
1. **API Client Layer** (`lib/api-client.ts`): Base HTTP client with authentication
2. **Service Layer** (`services/*-api.ts`): Type-safe API service functions
3. **React Hooks** (`hooks/api/*.ts`): React Query hooks for data fetching and mutations
4. **Backend Schemas** (`schemas/backend/*.ts`): Zod schemas matching backend domain models
## API Endpoints
### Authentication
- `POST /auth/login` - JWT authentication
### Organizations
- `GET /api/organizations` - List all organizations
- `GET /api/organizations/:id` - Get organization by ID
- `POST /api/organizations` - Create organization
- `DELETE /api/organizations/:id` - Delete organization
### Sites
- `POST /api/sites` - Create site
- `GET /api/sites/:id` - Get site by ID
- `GET /api/sites/business/:businessId` - Get sites by business
- `GET /api/sites/nearby?lat=&lng=&radius=` - Find sites within radius
- `DELETE /api/sites/:id` - Delete site
### Resource Flows
- `POST /api/resources` - Create resource flow
- `GET /api/resources/:id` - Get resource flow by ID
- `GET /api/resources/site/:siteId` - Get flows by site
- `GET /api/resources/business/:businessId` - Get flows by business
- `DELETE /api/resources/:id` - Delete resource flow
### Matching Engine
- `GET /api/matching/resource/:resourceId?max_distance_km=50&min_score=0.3&limit=20` - Find matches for a resource
## Data Models
### Organization
- Simplified compared to frontend's previous model
- No embedded needs/offers (these are now separate ResourceFlow entities)
- Fields: `ID`, `Name`, `Sector`, `Description`, `LogoURL`, `Website`, `Address`, `Verified`, `CreatedAt`, `UpdatedAt`
### Site
- Represents a physical location
- Fields: `ID`, `Name`, `Address`, `Latitude`, `Longitude`, `SiteType`, `FloorAreaM2`, `OwnerBusinessID`, `CreatedAt`, `UpdatedAt`
### ResourceFlow
- Represents input/output resource flows
- Direction: `input` or `output`
- Types: `heat`, `water`, `steam`, `CO2`, `biowaste`, `cooling`, `logistics`, `materials`, `service`
- Includes: `Quality`, `Quantity`, `TimeProfile`, `EconomicData`, `Constraints`, `ServiceDetails`
- Precision levels: `rough`, `estimated`, `measured`
- Source types: `declared`, `device`, `calculated`
### Match
- Represents a match between two resource flows
- Status: `suggested`, `negotiating`, `reserved`, `contracted`, `live`, `failed`, `cancelled`
- Includes: `CompatibilityScore`, `EconomicValue`, `DistanceKm`, `RiskAssessment`, `EconomicImpact`, `TransportationEstimate`
## Usage Examples
### Using Organizations API
```typescript
import { useOrganizations, useCreateOrganization } from '@/hooks/api';
function OrganizationsList() {
const { data: organizations, isLoading } = useOrganizations();
const createOrg = useCreateOrganization();
const handleCreate = async () => {
await createOrg.mutateAsync({
name: 'New Organization',
sector: '35.30',
description: 'Description',
});
};
// ...
}
```
### Using Resource Flows API
```typescript
import { useResourceFlowsByBusiness, useCreateResourceFlow } from '@/hooks/api';
function ResourceFlowsList({ businessId }: { businessId: string }) {
const { data: flows } = useResourceFlowsByBusiness(businessId);
const createFlow = useCreateResourceFlow();
const handleCreate = async () => {
await createFlow.mutateAsync({
business_id: businessId,
site_id: 'site-id',
direction: 'output',
type: 'heat',
quantity: {
amount: 500,
unit: 'kWh',
temporal_unit: 'per_hour',
},
quality: {
temperature_celsius: 65.0,
physical_state: 'liquid',
},
});
};
// ...
}
```
### Using Matching API
```typescript
import { useFindMatches } from '@/hooks/api';
function MatchesList({ resourceId }: { resourceId: string }) {
const { data: matchesData } = useFindMatches(resourceId, {
max_distance_km: 30,
min_score: 0.3,
limit: 10,
});
// matchesData.matches contains the array of matches
// matchesData.count contains the count
}
```
## Authentication
The `AuthContext` has been updated to:
- Use the API client's `login` function
- Decode JWT tokens to extract user information
- Store tokens in localStorage
- Automatically include Bearer tokens in API requests
## Migration Notes
### Breaking Changes
1. **Organization Model**: The frontend's previous organization model included embedded `needs` and `offers`. These are now separate `ResourceFlow` entities that must be created independently.
2. **Field Naming**: Backend uses Go's default JSON encoding (capitalized field names) for main structs, but snake_case for nested structs. The schemas reflect this.
3. **Data Structure**: Organizations no longer contain resource flows directly. Use `useResourceFlowsByBusiness(businessId)` to fetch related resource flows.
### Next Steps
1. Update components that display organizations to use the new API hooks
2. Create components for managing resource flows separately
3. Implement match visualization and management UI
4. Add error handling and loading states throughout
5. Consider adding optimistic updates for better UX
## Field Name Convention
**Note**: The backend Go structs use capitalized field names (Go's default JSON encoding) for main entities, but nested structs use snake_case JSON tags. The frontend schemas match this convention:
- Main struct fields: `ID`, `Name`, `Sector`, etc. (capitalized)
- Nested struct fields: `temperature_celsius`, `cost_in`, etc. (snake_case)
If the actual API responses differ, adjust the schemas accordingly.