Ewa Majewska
Software Engineer · AI Platform & Infrastructure
Warsaw, Poland
Software Engineer focused on backend services for AI-powered applications. Builds the API infrastructure that connects AI models to enterprise systems — SharePoint, Azure AD, and internal tools. Experienced in async Python, API gateway patterns, and distributed task processing. Collaborates closely with AI Lead Developers on integration challenges.
Expertise
- REST API development
- async Python
- SharePoint and Azure AD integration
- API gateway design
- task queue systems
Technologies
Work History
2025-01
Built internal developer portal for AI services — Swagger UI with curated examples, API key management, usage documentation, and interactive query playground.
Challenge: Documenting LLM endpoints is fundamentally different from regular REST APIs — behavior depends heavily on prompt context that cannot be fully specified in OpenAPI schema. Solved by adding example prompt/response pairs in endpoint descriptions and a dedicated examples section.
Learned: AI API documentation must include behavioral examples, not just parameter schemas. Without representative input/output examples, developers cannot predict how the endpoint will behave for their use case.
2024-09
Built metadata sync layer between PostgreSQL (source of truth) and Qdrant payload (search index). Ensures that metadata changes in SQL are reflected in Qdrant vector payloads within seconds.
Challenge: Keeping SQL and Qdrant consistent during failed transactions required careful handling. If the SQL commit succeeded but the Qdrant update failed, the systems would diverge. Implemented saga pattern with compensation actions and idempotent retry.
Learned: Dual-write consistency between a relational DB and a vector store is a distributed systems problem. There is no two-phase commit support — you need saga with compensation or accept eventual consistency with periodic reconciliation.
2024-05
Added WebSocket support for real-time task status updates — replaced frontend polling with server-push notifications when long-running tasks complete or encounter errors.
Challenge: WebSocket connections failed silently behind certain corporate HTTP proxies that don't support the WebSocket upgrade handshake. Added an automatic fallback to SSE (Server-Sent Events) for clients where WebSocket connection fails.
Learned: In enterprise environments with variable proxy configurations, always implement a fallback for WebSocket-dependent features. SSE is a reliable fallback for unidirectional server push.
2023-12
Implemented async task queue for long-running operations (document ingestion, batch embedding, report generation) using Celery with Redis as broker and result backend.
Challenge: Task results were being garbage-collected before the frontend polled for them. Default Celery result expiry is 24 hours, but our load balancer's keepalive timeout was causing some requests to complete after result expiry.
Learned: Always set Celery result backend TTL explicitly and coordinate with frontend polling frequency. The default TTL may be too short for long-running tasks in enterprise environments with strict network timeouts.
2023-09
Built API gateway for AI services — central entry point with request logging, Azure AD JWT validation, per-user rate limiting, and routing to multiple AI backends.
Challenge: Per-user rate limiting across multiple API replicas requires shared state — local in-memory counters do not work with horizontal scaling. Implemented Redis-based sliding window rate limiter shared across all replicas.
Learned: Rate limiting at the gateway level with Redis sliding window gives accurate enforcement without the approximation errors of fixed windows. The implementation is slightly more complex but worth it for fairness.
2023-05
Integrated SharePoint REST API for document retrieval — authenticating via Azure AD service principal using OAuth2 client credentials flow, retrieving documents and metadata from document libraries.
Challenge: Azure AD access tokens were being requested on every API call — each request triggered a token fetch adding 200-400ms latency. Implemented in-memory token cache with TTL set to 90% of the token's actual expiry time.
Learned: Always cache Azure AD tokens. They are valid for 1 hour and fetching a new one on every request is both slow and wasteful. The msal library has built-in caching but it requires explicit initialization.
2023-01
Built the REST API backend for internal document management system — FastAPI with PostgreSQL, Alembic migrations, full CRUD for documents and metadata, with concurrent write protection.
Challenge: Concurrent write conflicts under load — two requests updating the same document simultaneously would corrupt the version history. Implemented optimistic locking with a version column: update only succeeds if the version matches the client's expected value.
Learned: Optimistic locking is the right pattern for document update APIs with low conflict probability. Pessimistic locking (SELECT FOR UPDATE) is simpler but creates bottlenecks under concurrent access.