ameurb/algerian-government-services
If you are the rightful owner of algerian-government-services and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The Algerian Government Services Chat Application is a ChatGPT-like intelligent assistant designed to facilitate access to Algerian government services, featuring automatic RTL/LTR support, MongoDB Atlas integration, and a streaming HTTP-MCP server.
๐ฉ๐ฟ Enhanced AI Government Services Assistant
An advanced AI-powered assistant for Algerian government services with real-time streaming, SQLite database, and multilingual support (Arabic, English, French).
๐ Features
๐ง Advanced AI System
- AI-powered query analysis with intent detection
- Automatic language detection (Arabic, English, French)
- Real-time streaming responses with markdown formatting
- Human-like comprehensive guidance with step-by-step instructions
๐๏ธ SQLite Database
- Local file-based database for fast performance
- Comprehensive government services data
- Multilingual content with full translations
- Advanced search indexing for accurate results
๐ Real-time Streaming
- Character-by-character streaming for instant responses
- Professional markdown formatting in real-time
- Enhanced user experience with typing indicators
- Vercel AI SDK integration for optimal performance
๐ Multilingual Support
- Arabic (ุงูุนุฑุจูุฉ) - Primary language with RTL support
- English - Administrative terminology and procedures
- French (Franรงais) - Administrative French for legal context
๐ Quick Start
Prerequisites
- Node.js 18+
- OpenAI API key
- TypeScript knowledge (optional)
Installation
# Clone repository
git clone https://github.com/ameurb/algerian-government-services.git
cd algerian-government-services
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Add your OPENAI_API_KEY to .env
# Generate Prisma client and create database
npx prisma generate
npx prisma db push
# Seed database with government services
npx tsx prisma/sqlite-seed.ts
# Start development server
npm run dev
๐ก Streaming API Usage in Node.js
Basic Streaming Request
import fetch from 'node-fetch';
async function streamGovernmentServices(userQuery) {
const response = await fetch('https://dzservices.findapply.com/api/enhanced-chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
messages: [
{ role: 'user', content: userQuery }
],
sessionId: `session_${Date.now()}`
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let accumulatedText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\\n').filter(line => line.trim());
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
console.log('\\nโ
Streaming completed!');
console.log('\\n๐ Full Response:');
console.log(accumulatedText);
return accumulatedText;
}
try {
const parsed = JSON.parse(data);
if (parsed.content) {
accumulatedText += parsed.content;
process.stdout.write(parsed.content); // Real-time display
}
} catch (parseError) {
console.warn('Failed to parse:', data);
}
}
}
}
}
// Usage Examples
await streamGovernmentServices('ููู ุฃุญุตู ุนูู ุฌูุงุฒ ุงูุณูุฑุ');
await streamGovernmentServices('How to get a national ID?');
await streamGovernmentServices('Comment enregistrer une entreprise ?');
Advanced Streaming with Session Management
class AlgerianServicesClient {
constructor(apiKey = null) {
this.baseUrl = 'https://dzservices.findapply.com';
this.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
this.conversationHistory = [];
}
async streamChat(userMessage, onChunk = null, onComplete = null) {
// Add user message to history
this.conversationHistory.push({
role: 'user',
content: userMessage,
timestamp: new Date()
});
const response = await fetch(`${this.baseUrl}/api/enhanced-chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
messages: this.conversationHistory,
sessionId: this.sessionId
})
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullResponse = '';
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\\n').filter(line => line.trim());
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
// Add assistant response to history
this.conversationHistory.push({
role: 'assistant',
content: fullResponse,
timestamp: new Date()
});
if (onComplete) onComplete(fullResponse);
return fullResponse;
}
try {
const parsed = JSON.parse(data);
if (parsed.content) {
fullResponse += parsed.content;
if (onChunk) onChunk(parsed.content, fullResponse);
}
} catch (error) {
console.warn('Parse error:', error);
}
}
}
}
} finally {
reader.releaseLock();
}
return fullResponse;
}
// Get conversation history
getHistory() {
return this.conversationHistory;
}
// Clear conversation
clearHistory() {
this.conversationHistory = [];
this.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
}
// Usage Example
const client = new AlgerianServicesClient();
// Stream with real-time callback
await client.streamChat(
'ููู ุฃุณุฌู ุดุฑูุฉ ุฌุฏูุฏุฉุ',
(chunk, fullText) => {
// Called for each streaming chunk
console.log('๐ New chunk:', chunk);
},
(finalResponse) => {
// Called when streaming completes
console.log('โ
Final response length:', finalResponse.length);
}
);
// Continue conversation with context
await client.streamChat('ู
ุง ูู ุงููุซุงุฆู ุงูู
ุทููุจุฉุ');
console.log('๐ Conversation history:', client.getHistory());
Express.js Integration
import express from 'express';
import { AlgerianServicesClient } from './algerian-services-client.js';
const app = express();
app.use(express.json());
const client = new AlgerianServicesClient();
// Streaming endpoint
app.post('/api/stream-chat', async (req, res) => {
const { message, sessionId } = req.body;
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*'
});
try {
await client.streamChat(
message,
(chunk) => {
// Forward chunk to client
res.write(`data: ${JSON.stringify({ content: chunk })}\\n\\n`);
},
(finalResponse) => {
res.write('data: [DONE]\\n\\n');
res.end();
}
);
} catch (error) {
res.write(`data: ${JSON.stringify({ error: error.message })}\\n\\n`);
res.end();
}
});
app.listen(3000, () => {
console.log('๐ Server running on http://localhost:3000');
});
TypeScript Integration
interface StreamingResponse {
content?: string;
error?: string;
metadata?: {
tokensUsed?: number;
servicesFound?: number;
language?: string;
};
}
interface ConversationMessage {
role: 'user' | 'assistant';
content: string;
timestamp: Date;
}
class AlgerianServicesAPI {
private baseUrl: string;
private sessionId: string;
private history: ConversationMessage[];
constructor(baseUrl = 'https://dzservices.findapply.com') {
this.baseUrl = baseUrl;
this.sessionId = this.generateSessionId();
this.history = [];
}
async *streamResponse(userQuery: string): AsyncIterable<string> {
this.history.push({
role: 'user',
content: userQuery,
timestamp: new Date()
});
const response = await fetch(`${this.baseUrl}/api/enhanced-chat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: this.history,
sessionId: this.sessionId
})
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
const reader = response.body?.getReader();
const decoder = new TextDecoder();
let accumulatedText = '';
if (!reader) throw new Error('Response body not readable');
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\\n').filter(line => line.trim());
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
this.history.push({
role: 'assistant',
content: accumulatedText,
timestamp: new Date()
});
return;
}
try {
const parsed: StreamingResponse = JSON.parse(data);
if (parsed.content) {
accumulatedText += parsed.content;
yield parsed.content;
}
} catch (error) {
console.warn('Parse error:', error);
}
}
}
}
} finally {
reader.releaseLock();
}
}
private generateSessionId(): string {
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
getConversationHistory(): ConversationMessage[] {
return [...this.history];
}
}
// TypeScript Usage
const api = new AlgerianServicesAPI();
console.log('๐ค Starting AI conversation...');
for await (const chunk of api.streamResponse('ููู ุฃุญุตู ุนูู ุฌูุงุฒ ุงูุณูุฑุ')) {
process.stdout.write(chunk);
}
console.log('\\n๐ Conversation history:', api.getConversationHistory());
React.js Frontend Integration
import { useState, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
function useStreamingChat() {
const [messages, setMessages] = useState([]);
const [isStreaming, setIsStreaming] = useState(false);
const [currentStream, setCurrentStream] = useState('');
const streamMessage = async (userMessage: string) => {
// Add user message
setMessages(prev => [...prev, { role: 'user', content: userMessage }]);
setIsStreaming(true);
setCurrentStream('');
try {
const response = await fetch('/api/enhanced-chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: [...messages, { role: 'user', content: userMessage }],
sessionId: 'react_session'
})
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
let accumulated = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
setMessages(prev => [...prev, { role: 'assistant', content: accumulated }]);
setIsStreaming(false);
setCurrentStream('');
return;
}
try {
const parsed = JSON.parse(data);
if (parsed.content) {
accumulated += parsed.content;
setCurrentStream(accumulated);
}
} catch (error) {
console.warn('Parse error:', error);
}
}
}
}
} catch (error) {
console.error('Streaming error:', error);
setIsStreaming(false);
}
};
return { messages, isStreaming, currentStream, streamMessage };
}
// React Component
export default function ChatInterface() {
const { messages, isStreaming, currentStream, streamMessage } = useStreamingChat();
return (
<div className="chat-container">
{messages.map((msg, i) => (
<div key={i} className={`message ${msg.role}`}>
<ReactMarkdown>{msg.content}</ReactMarkdown>
</div>
))}
{isStreaming && currentStream && (
<div className="streaming-message">
<ReactMarkdown>{currentStream}</ReactMarkdown>
<span className="typing-cursor">|</span>
</div>
)}
<ChatInput onSend={streamMessage} disabled={isStreaming} />
</div>
);
}
๐๏ธ Architecture
Frontend (React/Next.js) โโ Streaming API โโ AI Analysis โโ SQLite Database
โ โ โ โ
User Input Enhanced Chat OpenAI GPT-4 Government Services
Markdown UI /api/enhanced-chat Query Analysis Local DB
Real-time UX Streaming Response Intent Detection Fast Search
๐ง System Components:
-
Frontend Application
- Real-time streaming UI with markdown parsing
- Multilingual interface (Arabic/English/French)
- Professional government services styling
-
AI-Powered Backend
- Vercel AI SDK for advanced query processing
- Automatic language detection and intent analysis
- Comprehensive response generation with templates
-
SQLite Database
- Local government services database
- Optimized for fast search and retrieval
- Multilingual content with proper indexing
๐ Available Services
Civil Status Services (ุงูุญุงูุฉ ุงูู ุฏููุฉ)
-
๐ Passport Services (ุฎุฏู ุงุช ุฌูุงุฒ ุงูุณูุฑ)
- New passport application / ุทูุจ ุฌูุงุฒ ุณูุฑ ุฌุฏูุฏ
- Passport renewal / ุชุฌุฏูุฏ ุฌูุงุฒ ุงูุณูุฑ
- Passport tracking / ู ุชุงุจุนุฉ ุทูุจ ุฌูุงุฒ ุงูุณูุฑ
-
๐ Identity Documents (ูุซุงุฆู ุงููููุฉ)
- National ID card / ุจุทุงูุฉ ุงูุชุนุฑูู ุงููุทููุฉ
- Birth certificates / ุดูุงุฏุงุช ุงูู ููุงุฏ
- Marriage certificates / ุดูุงุฏุงุช ุงูุฒูุงุฌ
Business Services (ุฎุฏู ุงุช ุงูุฃุนู ุงู)
- ๐ข Company Registration (ุชุณุฌูู ุงูุดุฑูุงุช)
- ๐ Commercial Licenses (ุงูุฑุฎุต ุงูุชุฌุงุฑูุฉ)
- ๐ผ Trade Register (ุงูุณุฌู ุงูุชุฌุงุฑู)
Education Services (ุฎุฏู ุงุช ุงูุชุนููู )
- ๐ Higher Education Grants (ู ูุญ ุงูุชุนููู ุงูุนุงูู)
- ๐ University Services (ุงูุฎุฏู ุงุช ุงูุฌุงู ุนูุฉ)
Transportation Services (ุฎุฏู ุงุช ุงูููู)
- ๐ Driving License (ุฑุฎุตุฉ ุงูุณูุงูุฉ)
- ๐ Vehicle Registration (ุชุณุฌูู ุงูู ุฑูุจุงุช)
๐งช Testing the Streaming API
Simple Test Script
# Test with Arabic query
curl -X POST https://dzservices.findapply.com/api/enhanced-chat \\
-H "Content-Type: application/json" \\
-d '{
"messages": [{"role": "user", "content": "ููู ุฃุญุตู ุนูู ุฌูุงุฒ ุงูุณูุฑุ"}],
"sessionId": "test_session"
}'
# Test with English query
curl -X POST https://dzservices.findapply.com/api/enhanced-chat \\
-H "Content-Type: application/json" \\
-d '{
"messages": [{"role": "user", "content": "How to get a passport?"}],
"sessionId": "test_session"
}'
# Test with French query
curl -X POST https://dzservices.findapply.com/api/enhanced-chat \\
-H "Content-Type: application/json" \\
-d '{
"messages": [{"role": "user", "content": "Comment obtenir un passeport ?"}],
"sessionId": "test_session"
}'
Expected Response Format
data: {"content":"#"}
data: {"content":" ๐ฏ"}
data: {"content":" Direct"}
data: {"content":" Answer"}
data: {"content":"\\n\\n"}
data: {"content":"To"}
data: {"content":" apply"}
data: {"content":" for"}
data: {"content":" an"}
data: {"content":" Algerian"}
data: {"content":" passport"}
data: {"content":"..."}
data: [DONE]
๐ Production Deployment
The application is deployed and available at:
- ๐ค Main Application: https://dzservices.findapply.com
- ๐ก Streaming API: https://dzservices.findapply.com/api/enhanced-chat
- ๐ง Alternative API: https://dzservices.findapply.com/api/chat-stream
Features in Production:
- โ Real-time AI streaming with markdown formatting
- โ SQLite database with comprehensive government services
- โ Multilingual support with automatic language detection
- โ Professional UI with enhanced user experience
- โ Error handling and graceful fallbacks
๐ API Support
Error Handling
The API returns structured errors:
{
"error": "Internal server error",
"message": "Specific error description",
"timestamp": "2025-01-15T10:30:00.000Z"
}
Rate Limiting
- Production: 60 requests per minute per IP
- Development: No limits
Response Times
- Average: 2-8 seconds for complete response
- Streaming: Immediate start, character-by-character delivery
- Database: < 100ms query response time
๐ค Contributing
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature
) - Commit changes (
git commit -m 'Add amazing feature'
) - Push to branch (
git push origin feature/amazing-feature
) - Open Pull Request
๐ License
This project is licensed under the MIT License - see the file for details.
๐ Built with โค๏ธ for the Algerian community ๐ฉ๐ฟ
Empowering citizens with intelligent AI-powered access to government services through advanced streaming technology.