Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools
Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
* GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
* GET /api/v1/users/me/organizations - User organizations
* POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue
API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules
Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
6.3 KiB
Proposals API
The Proposals API provides endpoints for managing symbiosis proposals between organizations. Proposals represent requests for resource exchange or collaboration opportunities.
Base URL
https://api.turash.com/api/v1
Endpoints
Get All Proposals
Retrieve all proposals with optional filtering.
Endpoint: GET /api/v1/proposals
Query Parameters:
status(optional): Filter by proposal status (pending,accepted,rejected)from_org(optional): Filter by proposing organization IDto_org(optional): Filter by target organization IDlimit(optional): Maximum number of results (default: 50)offset(optional): Pagination offset (default: 0)
Response:
[
{
"id": "proposal-123",
"from_org_id": "org-456",
"to_org_id": "org-789",
"resource_id": "resource-101",
"resource_type": "input",
"resource_name": "Organic Waste",
"message": "We can provide organic waste for your composting needs",
"status": "pending",
"created_at": "2024-01-15T10:30:00Z"
}
]
Get Proposal by ID
Retrieve a specific proposal by its ID.
Endpoint: GET /api/v1/proposals/{id}
Path Parameters:
id: Proposal ID
Response:
{
"id": "proposal-123",
"from_org_id": "org-456",
"to_org_id": "org-789",
"resource_id": "resource-101",
"resource_type": "input",
"resource_name": "Organic Waste",
"message": "We can provide organic waste for your composting needs",
"status": "pending",
"created_at": "2024-01-15T10:30:00Z"
}
Error Responses:
404 Not Found- Proposal not found
Get Proposals by Organization
Retrieve all proposals where an organization is either the sender or receiver.
Endpoint: GET /api/v1/organizations/{id}/proposals
Path Parameters:
id: Organization ID
Response:
{
"incoming": [
{
"id": "proposal-123",
"from_org_id": "org-456",
"to_org_id": "org-789",
"resource_id": "resource-101",
"resource_type": "input",
"resource_name": "Organic Waste",
"message": "We can provide organic waste for your composting needs",
"status": "pending",
"created_at": "2024-01-15T10:30:00Z"
}
],
"outgoing": [
{
"id": "proposal-124",
"from_org_id": "org-789",
"to_org_id": "org-456",
"resource_id": "resource-102",
"resource_type": "output",
"resource_name": "Heat Energy",
"message": "Interested in your heat recovery system",
"status": "accepted",
"created_at": "2024-01-16T14:20:00Z"
}
]
}
Create Proposal
Create a new symbiosis proposal.
Endpoint: POST /api/v1/proposals
Request Body:
{
"from_org_id": "org-456",
"to_org_id": "org-789",
"resource_id": "resource-101",
"resource_type": "input",
"resource_name": "Organic Waste",
"message": "We can provide organic waste for your composting needs"
}
Required Fields:
from_org_id: ID of the proposing organizationto_org_id: ID of the target organizationresource_id: ID of the resource flow being proposedresource_type: Direction of the resource flow (inputoroutput)resource_name: Human-readable name of the resource
Optional Fields:
message: Additional message or proposal details
Response:
{
"id": "proposal-123",
"from_org_id": "org-456",
"to_org_id": "org-789",
"resource_id": "resource-101",
"resource_type": "input",
"resource_name": "Organic Waste",
"message": "We can provide organic waste for your composting needs",
"status": "pending",
"created_at": "2024-01-15T10:30:00Z"
}
Error Responses:
400 Bad Request- Invalid request data404 Not Found- Organization or resource not found
Update Proposal Status
Update the status of an existing proposal.
Endpoint: POST /api/v1/proposals/{id}/status
Path Parameters:
id: Proposal ID
Request Body:
{
"status": "accepted"
}
Valid Status Values:
pending- Initial status, awaiting responseaccepted- Proposal accepted by target organizationrejected- Proposal rejected by target organization
Response:
{
"message": "Proposal status updated successfully"
}
Error Responses:
400 Bad Request- Invalid status value404 Not Found- Proposal not found
Data Types
Proposal Status
type ProposalStatus = 'pending' | 'accepted' | 'rejected';
Proposal Object
interface Proposal {
id: string;
from_org_id: string;
to_org_id: string;
resource_id: string;
resource_type: 'input' | 'output';
resource_name: string;
message?: string;
status: ProposalStatus;
created_at: string;
}
Business Rules
Proposal Lifecycle
- Creation: Proposals are created with
pendingstatus - Response: Target organization can accept or reject the proposal
- Final State: Once accepted or rejected, status cannot be changed
Validation Rules
- Organizations cannot propose to themselves
- Resource must exist and be owned by the proposing organization
- Resource type must match the direction being proposed
- Message length limited to 500 characters
Permissions
Currently, all proposal operations are publicly accessible. Future implementations will include:
- Authentication requirements
- Authorization based on organization membership
- Proposal creation limits per organization
Error Codes
| Code | Description |
|---|---|
VALIDATION_ERROR |
Request data validation failed |
PROPOSAL_NOT_FOUND |
Specified proposal does not exist |
ORGANIZATION_NOT_FOUND |
Specified organization does not exist |
RESOURCE_NOT_FOUND |
Specified resource does not exist |
INVALID_STATUS_TRANSITION |
Attempted invalid status change |
SELF_PROPOSAL_ERROR |
Organization cannot propose to itself |
Rate Limits
- Create Proposal: 10 per hour per organization
- Update Status: 50 per hour per organization
- Get Operations: 100 per hour per IP
WebSocket Events
The API emits WebSocket events for real-time proposal updates:
proposal_created: New proposal submittedproposal_status_changed: Proposal status updated
Event Payload:
{
"type": "proposal_status_changed",
"proposal_id": "proposal-123",
"old_status": "pending",
"new_status": "accepted",
"updated_by": "org-789",
"timestamp": "2024-01-15T10:35:00Z"
}