Opportunities Service
The Opportunities Service is a comprehensive system for managing job offers, project requests, and collaboration opportunities within the Ring platform. It provides full CRUD operations with advanced filtering, authentication, and internationalization support.
Overviewβ
The opportunities system connects companies, professionals, and projects through a structured marketplace that supports:
- Job Opportunities - Full-time and part-time positions
- Project Requests - Freelance and contract work
- Collaboration Offers - Partnership and joint venture opportunities
- Confidential Opportunities - Premium opportunities for verified members
- Multi-language Support - Ukrainian and English localization
- File Attachments - Supporting documents and portfolios
API Endpointsβ
Core Opportunity Managementβ
GET /api/opportunitiesβ
Retrieve a paginated list of opportunities with filtering and search capabilities.
Query Parameters:
page
(number, optional) - Page number for pagination (default: 1)limit
(number, optional) - Items per page (default: 10, max: 50)category
(string, optional) - Filter by opportunity categorytype
(string, optional) - Filter by opportunity type (job, project, collaboration)budget_min
(number, optional) - Minimum budget filterbudget_max
(number, optional) - Maximum budget filterlocation
(string, optional) - Location filterremote
(boolean, optional) - Remote work filtersearch
(string, optional) - Search in title and descriptionentity_id
(string, optional) - Filter by posting entitysort
(string, optional) - Sort field (created_at, budget, title)order
(string, optional) - Sort order (asc, desc)
Response:
{
"opportunities": [
{
"id": "opp_123",
"title": "Senior Full-Stack Developer",
"description": "We are looking for an experienced full-stack developer...",
"short_description": "Senior developer position with modern tech stack",
"category": "Software Development",
"type": "job",
"budget": {
"min": 3000,
"max": 5000,
"currency": "USD",
"per": "month"
},
"location": {
"city": "Kyiv",
"country": "Ukraine",
"remote": true
},
"requirements": [
"5+ years of experience",
"React, Node.js proficiency",
"English B2+"
],
"benefits": [
"Flexible schedule",
"Health insurance",
"Professional development"
],
"entity": {
"id": "entity_456",
"name": "TechCorp Ukraine",
"logo": "https://storage.com/logos/techcorp.png"
},
"attachments": [
{
"name": "job_description.pdf",
"url": "https://storage.com/attachments/job_desc.pdf",
"size": 245760
}
],
"application_process": {
"method": "email",
"contact": "hr@techcorp.ua",
"instructions": "Send CV and cover letter"
},
"tags": ["react", "nodejs", "typescript", "remote"],
"status": "active",
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-16T14:30:00Z",
"expires_at": "2024-03-15T23:59:59Z",
"views": 245,
"applications": 12
}
],
"pagination": {
"current_page": 1,
"total_pages": 15,
"total_items": 147,
"per_page": 10,
"has_next": true,
"has_prev": false
},
"filters": {
"categories": ["Software Development", "Design", "Marketing"],
"types": ["job", "project", "collaboration"],
"locations": ["Kyiv", "Lviv", "Kharkiv", "Remote"]
}
}
GET /api/opportunities/[id]β
Retrieve detailed information about a specific opportunity.
Path Parameters:
id
(string, required) - Opportunity identifier
Response:
{
"opportunity": {
"id": "opp_123",
"title": "Senior Full-Stack Developer",
"description": "Detailed job description with full requirements...",
"short_description": "Senior developer position with modern tech stack",
"category": "Software Development",
"type": "job",
"budget": {
"min": 3000,
"max": 5000,
"currency": "USD",
"per": "month"
},
"location": {
"city": "Kyiv",
"country": "Ukraine",
"remote": true,
"timezone": "Europe/Kiev"
},
"requirements": [
"5+ years of full-stack development experience",
"Expert knowledge of React and Node.js",
"TypeScript proficiency",
"English B2+ level"
],
"benefits": [
"Flexible working hours",
"Health and dental insurance",
"Professional development budget",
"Modern office in city center"
],
"entity": {
"id": "entity_456",
"name": "TechCorp Ukraine",
"logo": "https://storage.com/logos/techcorp.png",
"website": "https://techcorp.ua",
"employee_count": "50-100"
},
"contact_person": {
"name": "Anna Kovalenko",
"position": "HR Manager",
"email": "anna@techcorp.ua",
"phone": "+380123456789"
},
"application_process": {
"method": "form",
"instructions": "Please fill out the application form and attach your CV",
"required_documents": ["CV", "Cover Letter", "Portfolio"]
},
"attachments": [
{
"id": "att_789",
"name": "detailed_job_description.pdf",
"url": "https://storage.com/attachments/detailed_job.pdf",
"size": 512000,
"uploaded_at": "2024-01-15T10:00:00Z"
}
],
"tags": ["react", "nodejs", "typescript", "remote", "fintech"],
"status": "active",
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-16T14:30:00Z",
"expires_at": "2024-03-15T23:59:59Z",
"views": 245,
"applications": 12,
"is_featured": false,
"visibility": "public"
}
}
POST /api/opportunities/createβ
Create a new opportunity. Requires authentication and appropriate permissions.
Authentication: Required (Member role or higher)
Request Body:
{
"title": "Senior Full-Stack Developer",
"description": "We are looking for an experienced full-stack developer to join our growing team...",
"short_description": "Senior developer position with modern tech stack",
"category": "Software Development",
"type": "job",
"budget": {
"min": 3000,
"max": 5000,
"currency": "USD",
"per": "month"
},
"location": {
"city": "Kyiv",
"country": "Ukraine",
"remote": true
},
"requirements": [
"5+ years of experience",
"React, Node.js proficiency",
"English B2+"
],
"benefits": [
"Flexible schedule",
"Health insurance"
],
"entity_id": "entity_456",
"contact_person": {
"name": "Anna Kovalenko",
"position": "HR Manager",
"email": "anna@techcorp.ua"
},
"application_process": {
"method": "email",
"contact": "hr@techcorp.ua",
"instructions": "Send CV and cover letter"
},
"tags": ["react", "nodejs", "typescript"],
"expires_at": "2024-03-15T23:59:59Z",
"visibility": "public"
}
Response:
{
"success": true,
"opportunity": {
"id": "opp_new123",
"title": "Senior Full-Stack Developer",
"status": "pending",
"created_at": "2024-01-20T15:30:00Z"
},
"message": "Opportunity created successfully and is pending review"
}
PUT /api/opportunities/updateβ
Update an existing opportunity. Requires authentication and ownership/admin permissions.
Authentication: Required (Owner or Admin)
Request Body:
{
"id": "opp_123",
"title": "Updated Senior Full-Stack Developer Position",
"description": "Updated description...",
"budget": {
"min": 3500,
"max": 5500,
"currency": "USD",
"per": "month"
},
"status": "active",
"updated_fields": ["title", "description", "budget"]
}
Response:
{
"success": true,
"opportunity": {
"id": "opp_123",
"updated_at": "2024-01-20T16:45:00Z"
},
"message": "Opportunity updated successfully"
}
DELETE /api/opportunities/delete/[id]β
Delete an opportunity. Requires authentication and ownership/admin permissions.
Authentication: Required (Owner or Admin)
Path Parameters:
id
(string, required) - Opportunity identifier
Response:
{
"success": true,
"message": "Opportunity deleted successfully"
}
File Managementβ
POST /api/opportunities/uploadβ
Upload files and attachments for opportunities.
Authentication: Required
Content-Type: multipart/form-data
Form Data:
file
(File, required) - File to uploadopportunity_id
(string, required) - Opportunity identifierdescription
(string, optional) - File description
Response:
{
"success": true,
"attachment": {
"id": "att_789",
"name": "job_requirements.pdf",
"url": "https://storage.com/attachments/job_req.pdf",
"size": 245760,
"uploaded_at": "2024-01-20T17:00:00Z"
}
}
Premium Contentβ
GET /api/confidential/opportunitiesβ
Access confidential opportunities for premium members.
Authentication: Required (Confidential role or higher)
Query Parameters: Same as regular opportunities endpoint
Response: Similar structure to regular opportunities but includes premium content
Frontend Integrationβ
Page Routesβ
The opportunities system is fully integrated with Next.js 15 App Router:
/[locale]/opportunities
β
Bundle Size: 1.95 kB + 106 kB
- Opportunity listing page with filtering and search
- Pagination and infinite scroll support
- Category-based navigation
- Responsive grid layout
/[locale]/opportunities/[id]
β
Bundle Size: 1.95 kB + 106 kB
- Detailed opportunity view
- Application process integration
- Related opportunities suggestions
- Social sharing capabilities
/[locale]/opportunities/add
β
Bundle Size: 3.98 kB + 295 kB
- Opportunity creation form
- Rich text editor for descriptions
- File upload interface
- Form validation and error handling
/[locale]/confidential/opportunities
β
Bundle Size: 1.26 kB + 112 kB
- Premium opportunities for verified members
- Enhanced opportunity details
- Priority application processing
React Componentsβ
Key components for opportunities functionality:
// Opportunity listing component
<OpportunityList
opportunities={opportunities}
filters={filters}
onFilterChange={handleFilterChange}
pagination={pagination}
/>
// Opportunity card component
<OpportunityCard
opportunity={opportunity}
showActions={true}
compact={false}
/>
// Opportunity creation form
<OpportunityForm
onSubmit={handleSubmit}
initialData={initialData}
entityId={entityId}
/>
// Application process component
<ApplicationProcess
opportunity={opportunity}
user={user}
onApply={handleApplication}
/>
Service Architectureβ
Data Modelsβ
Opportunity Model:
interface Opportunity {
id: string
title: string
description: string
short_description?: string
category: string
type: 'job' | 'project' | 'collaboration'
budget?: {
min?: number
max?: number
currency: string
per: 'hour' | 'day' | 'month' | 'project'
}
location: {
city?: string
country?: string
remote: boolean
timezone?: string
}
requirements: string[]
benefits: string[]
entity_id: string
entity?: Entity
contact_person?: ContactPerson
application_process: ApplicationProcess
attachments: Attachment[]
tags: string[]
status: 'draft' | 'pending' | 'active' | 'expired' | 'closed'
visibility: 'public' | 'members' | 'confidential'
created_at: string
updated_at: string
expires_at?: string
views: number
applications: number
is_featured: boolean
}
Database Operationsβ
The service uses Firebase Firestore with optimized queries:
// Collection reference
const opportunitiesRef = collection(db, 'opportunities')
// Query with filters
const query = query(
opportunitiesRef,
where('status', '==', 'active'),
where('category', 'in', categories),
orderBy('created_at', 'desc'),
limit(10)
)
// Real-time subscription
const unsubscribe = onSnapshot(query, (snapshot) => {
const opportunities = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}))
})
Authentication & Authorizationβ
Access control is implemented at multiple levels:
Public Access:
- View active opportunities
- Browse categories and filters
- Access opportunity details
Member Access:
- Create opportunities (with entity ownership)
- Update owned opportunities
- Access application tracking
Confidential Access:
- View confidential opportunities
- Priority placement in listings
- Enhanced opportunity analytics
Admin Access:
- Moderate all opportunities
- Manage opportunity categories
- Access comprehensive analytics
Integration Examplesβ
Creating an Opportunityβ
import { createOpportunity } from '@/lib/opportunities-service'
const handleCreateOpportunity = async (formData: OpportunityFormData) => {
try {
const opportunity = await createOpportunity({
title: formData.title,
description: formData.description,
category: formData.category,
type: formData.type,
budget: formData.budget,
location: formData.location,
requirements: formData.requirements,
entity_id: userEntity.id,
expires_at: formData.expiresAt
})
router.push(`/${locale}/opportunities/${opportunity.id}`)
} catch (error) {
toast.error('Failed to create opportunity')
}
}
Searching Opportunitiesβ
import { searchOpportunities } from '@/lib/opportunities-service'
const handleSearch = async (filters: OpportunityFilters) => {
try {
const result = await searchOpportunities({
search: filters.search,
category: filters.category,
location: filters.location,
remote: filters.remote,
budget_min: filters.budgetMin,
budget_max: filters.budgetMax,
page: filters.page,
limit: 20
})
setOpportunities(result.opportunities)
setPagination(result.pagination)
} catch (error) {
toast.error('Search failed')
}
}
Applying to Opportunityβ
import { applyToOpportunity } from '@/lib/opportunities-service'
const handleApply = async (opportunityId: string, applicationData: ApplicationData) => {
try {
await applyToOpportunity(opportunityId, {
cover_letter: applicationData.coverLetter,
cv_url: applicationData.cvUrl,
portfolio_url: applicationData.portfolioUrl,
availability: applicationData.availability
})
toast.success('Application submitted successfully')
} catch (error) {
toast.error('Failed to submit application')
}
}
Performance Optimizationβ
Caching Strategyβ
- Client-side caching using React Query for opportunity listings
- Server-side caching for frequently accessed opportunities
- CDN caching for opportunity attachments and images
- Database indexing on commonly filtered fields
Bundle Optimizationβ
The opportunities system is optimized for performance:
- Code splitting with dynamic imports for heavy components
- Lazy loading for opportunity images and attachments
- Pagination to limit data transfer
- Optimistic updates for improved user experience
SEO & Internationalizationβ
- Localized URLs (
/en/opportunities
,/uk/opportunities
) - Meta tags with opportunity-specific information
- Schema.org markup for job posting structured data
- Sitemap generation for opportunity pages
- Hreflang tags for multilingual SEO
Error Handlingβ
Comprehensive error handling across the service:
// API error responses
{
"error": true,
"code": "OPPORTUNITY_NOT_FOUND",
"message": "The requested opportunity could not be found",
"details": {
"opportunity_id": "opp_123",
"timestamp": "2024-01-20T18:00:00Z"
}
}
// Common error codes
- OPPORTUNITY_NOT_FOUND
- UNAUTHORIZED_ACCESS
- VALIDATION_ERROR
- ENTITY_REQUIRED
- QUOTA_EXCEEDED
- UPLOAD_FAILED
Monitoring & Analyticsβ
Metrics Trackedβ
- Opportunity views and engagement metrics
- Application conversion rates by category
- Search performance and popular filters
- User interaction patterns and drop-off points
- File upload success rates and performance
Performance Monitoringβ
- API response times for all endpoints
- Database query performance optimization
- Bundle size monitoring for frontend components
- Error rate tracking and alerting
The Opportunities Service provides a comprehensive, scalable solution for managing job postings and project opportunities within the Ring platform, with full internationalization support and optimized performance.