15 KiB
API Integration Guide - tilbudsgiveren.alw.dk
Overview
This repository contains 565 executable GraphQL API scripts for the Ordrestyring API (https://graphql.ordrestyring.dk/graphql), ready for integration into the React frontend at tilbudsgiveren.alw.dk.
Quick Stats
- Total Endpoints: 566 (255 queries + 311 mutations)
- Scripts Created: 565 (99.8% coverage)
- Tested Queries: 255 (100%)
- Documented Mutations: 310 (99.7%)
- Output Files: 144
Architecture
Backend Structure
/home/w34078/scripts/apitest/
├── apikey # API authentication token
├── apiendpoint # GraphQL endpoint URL
├── examples/ # All executable scripts
│ ├── curl_*.sh # 255 query scripts (read operations)
│ ├── mutation_*.sh # 310 mutation scripts (write operations)
│ └── output/ # 144 saved API responses
└── [BATCH_*.md] # Documentation files
Integration Strategy
Phase 1: Query Integration (Safe - Read-Only)
Status: ✅ Ready for immediate integration
All 255 query scripts are safe to use in production - they only read data.
Categories Available:
-
Core Business (19 queries)
curl_cases.sh,curl_customers.sh,curl_offers.sh,curl_products.shcurl_invoices.sh,curl_users.sh,curl_departments.sh
-
Case Management (30+ queries)
- Case details, activities, materials, confirmations
- Case statuses, templates, types
-
Customer Data (20+ queries)
- Customers, contacts, categories, documents
- Customer activities, employee types
-
Invoicing (25+ queries)
- Sales invoices, creditor invoices, drafts
- Invoice additions, receiver info, payment data
-
Finance (15+ queries)
- Finance agreements, contracts, calculations
- Budget adjustments, completion grades
-
Products & Services (30+ queries)
- Products, services, installations
- Materials, schemes, offers
-
Documents & Files (20+ queries)
- Documentation folders, files, comments
- Appendixes, templates
-
System Configuration (40+ queries)
- Settings, VAT types, payment terms
- Discount groups, hour types, pause types
React Integration Example:
// Frontend: tilbudsgiveren.alw.dk/src/api/queries.js
export const fetchCases = async () => {
const query = `
query GetCases($pagination: Pagination) {
cases(pagination: $pagination) {
items {
id
caseNumber
customer { id name }
status { id name }
createdAt
}
totalCount
}
}
`;
const response = await fetch('https://graphql.ordrestyring.dk/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.REACT_APP_API_KEY}`
},
body: JSON.stringify({ query, variables: { pagination: { page: 1, limit: 20 } } })
});
return response.json();
};
Phase 2: Safe Mutation Integration (Low Risk)
Status: ✅ Ready with caution
24 safe mutations available:
mutation_mark_message_as_read.sh- Mark messages as read (idempotent)mutation_set_named_preference.sh- Set user preferences (safe)mutation_send_*_via_email.sh- Send notifications (7 scripts)mutation_approve_scheme.sh- Approve schemesmutation_register_*.sh- Registration operations
Integration Notes:
- ✅ Idempotent operations (can run multiple times safely)
- ⚠️ Send operations trigger real emails - use carefully
- ✅ Only affect current user or specific resources
Phase 3: Update Mutation Integration (Medium Risk)
Status: ⚠️ Requires test environment first
78 update mutations documented:
- All
mutation_update_*.shscripts modify existing data - Require valid production IDs
- Recommend test environment setup before integration
Categories:
- Case updates (6): updateCase, updateCaseMaterial, updateCaseStatus, etc.
- Customer updates (5): updateCustomer, updateContactPerson, etc.
- Invoice updates (4): updateCreditorInvoice, updateSalesInvoiceDraft, etc.
- Product/Offer updates (8): updateProduct, updateOffer, updateOfferLine, etc.
- Finance updates (10): updateFinanceAgreement, updateFinanceContract, etc.
- Configuration updates (45): updateSettings, updatePdfDesign, etc.
Phase 4: Create/Delete Operations (High Risk)
Status: 🔴 Documentation only - NOT for production without rollback strategy
208 dangerous mutations:
- 75 create mutations (
mutation_create_*.sh) - 59 delete mutations (
mutation_delete_*.sh) - 44 upload/move/transfer operations
- 30 mixed operations (bulk, change, copy, etc.)
⚠️ CRITICAL REQUIREMENTS:
- Test environment mandatory
- Rollback procedures documented
- User confirmation dialogs required
- Audit logging essential
- Backup before execution
Backend API Wrapper
Recommended Node.js Backend Structure
// backend/src/graphql/client.js
const { GraphQLClient } = require('graphql-request');
const client = new GraphQLClient('https://graphql.ordrestyring.dk/graphql', {
headers: {
authorization: `Bearer ${process.env.API_KEY}`,
},
});
module.exports = client;
// backend/src/routes/cases.js
const express = require('express');
const router = express.Router();
const client = require('../graphql/client');
// Safe read operation
router.get('/cases', async (req, res) => {
const query = `
query GetCases($pagination: Pagination) {
cases(pagination: $pagination) {
items { id caseNumber customer { name } }
totalCount
}
}
`;
try {
const data = await client.request(query, {
pagination: { page: 1, limit: 20 }
});
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Medium risk - update operation
router.put('/cases/:id', async (req, res) => {
const mutation = `
mutation UpdateCase($id: Int!, $input: CaseInput!) {
updateCase(id: $id, input: $input) {
id
caseNumber
updatedAt
}
}
`;
try {
// Add validation here
if (!req.body.input) {
return res.status(400).json({ error: 'Input required' });
}
const data = await client.request(mutation, {
id: parseInt(req.params.id),
input: req.body.input
});
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = router;
React Frontend Integration
// frontend/src/api/casesAPI.js
const API_BASE = process.env.REACT_APP_BACKEND_URL || 'http://localhost:3001';
export const casesAPI = {
// Safe read operation
getCases: async (page = 1, limit = 20) => {
const response = await fetch(`${API_BASE}/api/cases?page=${page}&limit=${limit}`);
if (!response.ok) throw new Error('Failed to fetch cases');
return response.json();
},
// Medium risk update
updateCase: async (caseId, caseData) => {
const response = await fetch(`${API_BASE}/api/cases/${caseId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: caseData })
});
if (!response.ok) throw new Error('Failed to update case');
return response.json();
}
};
// frontend/src/components/CaseList.jsx
import React, { useEffect, useState } from 'react';
import { casesAPI } from '../api/casesAPI';
export const CaseList = () => {
const [cases, setCases] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchCases = async () => {
try {
const data = await casesAPI.getCases();
setCases(data.cases.items);
} catch (error) {
console.error('Error fetching cases:', error);
} finally {
setLoading(false);
}
};
fetchCases();
}, []);
if (loading) return <div>Loading...</div>;
return (
<div>
<h2>Cases</h2>
{cases.map(c => (
<div key={c.id}>
{c.caseNumber} - {c.customer?.name}
</div>
))}
</div>
);
};
Script Usage
Direct Script Execution
All scripts in examples/ directory are executable:
# Query examples (safe - read-only)
./examples/curl_cases.sh
./examples/curl_customers.sh
./examples/curl_products.sh
# With parameters
./examples/curl_customer.sh 123
# Mutation examples (check --help first)
./examples/mutation_mark_message_as_read.sh --help
./examples/mutation_update_case.sh --help
Converting Scripts to API Calls
Each script contains the GraphQL query/mutation that can be extracted:
# Extract GraphQL query from script
grep -A 50 'query' examples/curl_cases.sh
Authentication
API Key Setup
# Current setup (apikey file)
export API_KEY="<ORDRESTYRING_API_TOKEN>"
export GRAPHQL_ENDPOINT="https://graphql.ordrestyring.dk/graphql"
Environment Variables for React
# .env.production
REACT_APP_BACKEND_URL=https://api.tilbudsgiveren.alw.dk
REACT_APP_GRAPHQL_ENDPOINT=https://graphql.ordrestyring.dk/graphql
# Backend .env
API_KEY=<ORDRESTYRING_API_TOKEN>
GRAPHQL_ENDPOINT=https://graphql.ordrestyring.dk/graphql
PORT=3001
Available Endpoints by Category
1. Cases (35 endpoints)
- Queries: cases, case, caseActivities, caseStatuses, caseTypes, caseTemplates, etc.
- Mutations: createCase, updateCase, deleteCase, changeCaseStatus, copyCase
2. Customers (25 endpoints)
- Queries: customers, customer, customerCategories, contactPersons, etc.
- Mutations: createCustomer, updateCustomer, deleteCustomer, anonymizeCustomers
3. Offers (20 endpoints)
- Queries: offers, offer, offerStatuses, offerTypes, offerLines, etc.
- Mutations: createOffer, updateOffer, deleteOffer, convertOfferToCase, copyOffer
4. Invoices (30 endpoints)
- Queries: salesInvoices, creditorInvoices, invoiceAdditions, paymentData, etc.
- Mutations: createInvoice, updateInvoice, sendSalesInvoiceViaEmail, applyPayment
5. Products (15 endpoints)
- Queries: products, product, materials, suppliers, priceGroups
- Mutations: createProduct, updateProduct, deleteProduct
6. Services (12 endpoints)
- Queries: services, service, serviceTypes, serviceActivities
- Mutations: createService, updateService, deleteService, addInstallationToService
7. Hours & Time (15 endpoints)
- Queries: hours, hour, hourTypes, pauses, pauseTypes
- Mutations: createHour, updateHour, deleteHour, bulkUpdateHours, moveCaseHours
8. Finance (20 endpoints)
- Queries: financeAgreements, financeContracts, budgetAdjustments, etc.
- Mutations: addFinanceAgreement, updateFinanceContract, etc.
9. Documentation (18 endpoints)
- Queries: documentationFolders, documentationFiles, fileComments
- Mutations: uploadDocumentationFile, createFolder, moveDocumentationFiles
10. Settings & Configuration (50+ endpoints)
- Queries: settings, reminderSettings, vatTypes, paymentTerms, discountGroups
- Mutations: updateSettings, updateReminderSettings, setUserPreferences
11. Users & Departments (10 endpoints)
- Queries: users, user, departments, employees
- Mutations: updateCurrentUser, updateUser, createDepartment
12. Schemes (15 endpoints)
- Queries: schemes, schemeTemplates, schemeQuestions
- Mutations: createScheme, updateScheme, approveScheme, addSchemeToCase
Safety Levels
🟢 Safe to Integrate Immediately
- All 255 query scripts - Read-only operations
- 24 safe mutations - Idempotent or non-destructive operations
- See
BATCH_12_SUMMARY.mdfor list
🟡 Integrate with Validation
- 78 update mutations - Modify existing data
- Require input validation
- Need error handling
- See
BATCHES_14_15_SUMMARY.md
🔴 Requires Test Environment
- 75 create mutations - Add new records
- 59 delete mutations - Remove records
- 44 upload/move operations - File and data manipulation
- 30 mixed operations - Bulk, copy, convert operations
- See
BATCHES_16_22_SUMMARY.md
Testing Strategy
1. Query Testing (Complete ✅)
- All 255 queries tested in production
- 144 output files saved in
examples/output/ - Safe to use directly
2. Safe Mutation Testing
// Test in development first
const testEnvironment = {
apiKey: process.env.TEST_API_KEY,
endpoint: process.env.TEST_GRAPHQL_ENDPOINT
};
// Then migrate to production
const productionEnvironment = {
apiKey: process.env.PROD_API_KEY,
endpoint: 'https://graphql.ordrestyring.dk/graphql'
};
3. Dangerous Operation Testing
- Set up staging/test database
- Implement rollback procedures
- Add user confirmation dialogs
- Log all operations
- Test delete with immediate restore
Next Steps for Integration
Immediate (Week 1)
- ✅ Set up Node.js backend with GraphQL client
- ✅ Integrate 10-20 core query endpoints (cases, customers, offers)
- ✅ Create React components for data display
- ✅ Test read operations in production
Short-term (Week 2-3)
- ⚠️ Integrate safe mutations (mark as read, send emails)
- ⚠️ Add user preference management
- ⚠️ Implement notification system
Medium-term (Month 2)
- 🔴 Set up test environment
- 🔴 Integrate update mutations with validation
- 🔴 Add audit logging
Long-term (Month 3+)
- 🔴 Carefully integrate create/delete operations
- 🔴 Implement full rollback system
- 🔴 Add comprehensive error handling
Documentation Files
All batch documentation available in repository:
BATCH_*_PLAN.md- Planning documents for each batchBATCH_*_SUMMARY.md- Completion summaries with statisticsEXPANSION_PLAN.md- Overall project statusREADME.md- User-facing documentationAPI_INTEGRATION_GUIDE.md- This file
Support & Maintenance
Script Locations
- Queries:
/home/w34078/scripts/apitest/examples/curl_*.sh - Mutations:
/home/w34078/scripts/apitest/examples/mutation_*.sh - Outputs:
/home/w34078/scripts/apitest/examples/output/*.json
Getting Help
Each script has --help documentation:
./examples/mutation_update_case.sh --help
Common Patterns
Pagination:
query GetCases($pagination: Pagination) {
cases(pagination: $pagination) {
items { id }
totalCount
}
}
# Variables: { "pagination": { "page": 1, "limit": 20 } }
Filtering:
query GetCustomers($filter: CustomerFilter) {
customers(filter: $filter) {
items { id name }
}
}
Mutations with Input:
mutation UpdateCase($id: Int!, $input: CaseInput!) {
updateCase(id: $id, input: $input) {
id
caseNumber
updatedAt
}
}
Performance Considerations
- Use pagination for large datasets (default: 20 items per page)
- Implement caching for frequently accessed data
- Use GraphQL field selection (only request needed fields)
- Batch operations where possible (bulkUpdate* mutations)
- Monitor API rate limits
Security Checklist
- ✅ API key stored in environment variables (never in code)
- ✅ Backend validates all user input
- ✅ HTTPS only for API communication
- ⚠️ Implement user authentication/authorization
- ⚠️ Rate limiting on backend
- ⚠️ Audit logging for mutations
- ⚠️ User confirmation for dangerous operations
Last Updated: October 23, 2025
Coverage: 565/566 endpoints (99.8%)
Status: Ready for integration
Contact: System documented and ready for React frontend integration at tilbudsgiveren.alw.dk