Start with one working example. Build and test a small invoice importer, then explain your decisions. Use it to connect your Python, SQL and system-design preparation.
- Official facts: The backend opening describes Python data handling and Django APIs. PostgreSQL and AWS are desirable skills.
- PracHub practice: Check amounts, tenant boundaries and retries, then explain why each check matters. The eleven prompts are original exercises, not reported employer questions.
Understand the domain first. Accounts payable concerns money an organization owes suppliers. A repeated invoice, missing credit or incorrect amount can change a payment decision. Keep three ideas visible in your practice work:
- Identity: Which tenant, supplier and invoice does this record belong to?
- Accuracy: What currency and amount does it represent?
- Traceability: Can a reviewer follow the result back to the original row?
Talent Partner introduction
officialOfficial: A short introductory conversation about your background and the opportunity.
- Format
- Teams conversation
- Interviewer
- Talent Partner
What to demonstrate
- Relevance: Connect one backend project to a problem its users needed solved.
- Ownership: Separate your contribution from the team’s overall result.
How to prepare
- Prepare a concise introduction: problem, action and outcome.
- Explain why invoice accuracy or reliable data processing interests you.
Hiring Manager discussion
officialOfficial: A discussion of your experience and fit for the team.
- Format
- Teams meeting
- Duration
- 30–45 minutes
- Interviewer
- Hiring Manager
What to demonstrate
- Judgment: Explain a tradeoff, including the alternative you rejected.
- Learning: Give a concrete example of applying something new.
How to prepare
- Choose a project you can explain without internal terminology.
- Bring an example of a review comment that improved your code.
Technical task or presentation
officialOfficial: A role-relevant task or presentation. The posting does not specify a delivery mode or duration.
- Format
- Role-relevant task or presentation
What to demonstrate
- Correctness: Make assumptions and failure cases explicit.
- Explanation: Connect your data structures, tests and tradeoffs to the problem.
How to prepare
- Practise a small Python change with a reproducible test command.
- Explain one incomplete extension and the next test you would add.
Leadership and co-founder conversation
officialOfficial: An office meeting with senior leadership and co-founders.
- Format
- In-person meeting at the office
- Interviewer
- Senior leadership and co-founders
What to demonstrate
- Product judgment: Explain how an engineering choice affected users.
- Responsibility: Describe what you did after a mistake or disagreement.
How to prepare
- Prepare one delivery story and one incident story with real outcomes.
- Bring a question about how finance-user feedback shapes engineering priorities.
PracHub editorial advice for the preparation topics above.
Silently rounding money
Set the precision policy first. Reject an amount that needs rounding unless the contract explicitly permits it. Keep currency separate from amount.
Treating an invoice ID as globally unique
Include tenant and supplier scope. Test two customers with the same invoice reference. Apply the boundary to both list and detail endpoints.
Automatically acting on a possible duplicate
Preserve the evidence for review. A matching signature identifies a candidate, not permission to delete a record or change a payment.
Submitting an example that is hard to run
Provide one verification command. Include input, expected output and a failing case. A reviewer should be able to reproduce the result from those instructions.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Parse an invoice amount exactly
Task: Implement minor_units(text, scale). Accept at most 64 characters, an optional minus and scale 0–4. Return an integer only for exactly representable amounts; reject exponent notation and non-finite values.
Approach
- Validate the grammar and currency scale.
- Convert directly with Decimal; reject any required rounding.
Worked solution 30 min
- Parse directly: Decimal preserves the input’s decimal value; converting through float first defeats that purpose.
- Bound the input: The grammar excludes whitespace, separators and exponents. Scale comes from currency policy.
- Check exactness: Extra trailing zeros are acceptable; unsupported precision raises ValueError. The implementation uses O(n) storage for bounded input length n.
import re
from decimal import Decimal, localcontext
def minor_units(text, scale):
if type(scale) is not int or not 0 <= scale <= 4:
raise ValueError("scale must be an integer from 0 to 4")
if (not isinstance(text, str) or len(text) > 64
or re.fullmatch(r"-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?", text) is None):
raise ValueError("invalid amount syntax")
with localcontext() as context:
context.prec = max(28, len(text) + scale + 2)
scaled = Decimal(text) * (Decimal(10) ** scale)
if scaled != scaled.to_integral_value():
raise ValueError("amount exceeds currency precision")
return int(scaled)
assert minor_units("12.340", 2) == 1234
assert minor_units("-0.25", 2) == -25
assert minor_units("500", 0) == 500
Scroll sideways to view long lines.
Follow-up
- Which document types should permit negative adjustments?
Group duplicate invoice candidates
Task: Group records by tenant, supplier, currency, amount and reference. Trim and case-fold references, preserving punctuation. Send missing references to review.
Approach
- Build a complete signature; retain original records.
- Return groups with at least two records.
Follow-up
- How would you measure false positives before using a broader matching rule?
Reconcile repeated statement lines
Task: Compare validated statement and ledger tuples for one tenant and supplier. Return missing and extra occurrences, including repeated identical rows.
Approach
- Count each
(reference, currency, amount)tuple. - Subtract counts in both directions; a set would erase repetitions.
Follow-up
- How would a different reporting cutoff affect the comparison?
Calculate outstanding balances
Task: Query invoices and partial payments by tenant and invoice ID. Keep unpaid invoices, preserve currency and report overpayments as negative balances.
Approach
- Sum payments before joining invoices.
- Use a left join and zero for missing payment totals.
Worked solution 35 min
- Aggregate first: Reduce payments to one total per tenant and invoice.
- Preserve invoices: Left join the total and use zero when no payment exists.
- Keep meaning: Retain currency and negative outstanding amounts; do not silently erase overpayments.
CREATE TABLE invoices (
tenant_id TEXT, invoice_id TEXT, currency TEXT, gross_minor INTEGER,
PRIMARY KEY (tenant_id, invoice_id)
);
CREATE TABLE payments (
tenant_id TEXT, invoice_id TEXT, paid_minor INTEGER
);
INSERT INTO invoices VALUES
('a','i1','GBP',10000), ('a','i2','USD',5000), ('b','i1','GBP',7000);
INSERT INTO payments VALUES
('a','i1',3000), ('a','i1',2000), ('b','i1',8000);
WITH paid AS (
SELECT tenant_id, invoice_id, SUM(paid_minor) AS total_paid
FROM payments
GROUP BY tenant_id, invoice_id
)
SELECT i.tenant_id, i.invoice_id, i.currency,
i.gross_minor - COALESCE(p.total_paid, 0) AS outstanding_minor
FROM invoices AS i
LEFT JOIN paid AS p
ON p.tenant_id = i.tenant_id AND p.invoice_id = i.invoice_id
ORDER BY i.tenant_id, i.invoice_id;
Scroll sideways to view long lines.
Follow-up
- How should reversals appear in the payment history?
Find the latest review status
Task: From append-only review events, find alerts whose latest status is open or investigating. Break timestamp ties using event ID.
Approach
- Rank all events within each tenant and alert.
- Select the newest row before filtering its status.
Follow-up
- What goes wrong if resolved events are removed before ranking?
Design an import that tolerates retries
Task: Import invoice files for multiple tenants. Retries and worker crashes must not duplicate records. Preserve source rows, rejected-row reasons and progress.
Which invoice-import worker may commit?
Choose a scenario to trace what changes.
One worker owns an accepted invoice file.
- 01Claim the importRecord the tenant, immutable file fingerprint and current ownership token.
- 02Validate a batchPreserve source row numbers and separate rejected rows from accepted records.
- 03Commit rows and checkpointCheck the token atomically with source-record uniqueness and the next durable checkpoint.
Commit the batch only while its ownership token remains current.
PracHub import-worker model. A token identifies the current worker; it must be checked in the same transaction as the imported rows and checkpoint. These are practice scenarios, not a description of Xelix infrastructure.
Approach
- Separate upload acceptance, validation and committed records.
- Name the unique keys, checkpoint and transaction boundaries.
Worked solution 45 min
- Accept: Authorize the tenant. Store a durable operation with a unique request key and content fingerprint; reject conflicting reuse.
- Stage: Retain the source file and row numbers. Separate incomplete uploads from accepted data.
- Commit: Write records, provenance and the next checkpoint in one transaction. Enforce source-record uniqueness.
- Notify: Use a transactional outbox for downstream analysis. Deduplicate alerts by rule version and evidence pair.
- Recover: A crash before commit repeats the batch; after commit, resume from the durable checkpoint. Reject writes from expired worker generations.
- Review: Preserve analyst decisions separately from generated alerts.
Follow-up
- What happens if the same request key arrives with different file contents?
Design auditable review actions
Task: Let analysts resolve and reopen alerts without allowing a stale screen to overwrite a newer decision.
Approach
- Require the version the analyst actually reviewed.
- Commit each accepted state change and audit event together.
Follow-up
- How does a repeated request differ from a conflicting new action?
Debug a report that doubles payments
Task: Joining two payments to two alert rows doubles an invoice’s payment total. Repair the query without losing legitimate equal-valued payments.
Approach
- Inspect the four-row intermediate join.
- Aggregate each measure separately before joining the results.
Worked solution 30 min
- Reproduce: Two payments combined with two alerts produce four rows, so the naive SUM returns 20000.
- Repair: Aggregate payments and alerts independently by tenant and invoice before joining.
- Prove the fix: Both payments equal 5000. SUM(DISTINCT) incorrectly returns 5000; the correct total is 10000.
CREATE TABLE invoices (
tenant_id TEXT, invoice_id TEXT, gross_minor INTEGER,
PRIMARY KEY (tenant_id, invoice_id)
);
CREATE TABLE payments (
tenant_id TEXT, invoice_id TEXT, paid_minor INTEGER
);
CREATE TABLE alert_events (
tenant_id TEXT, invoice_id TEXT, alert_id TEXT
);
INSERT INTO invoices VALUES ('a','i1',10000), ('b','i1',9000);
INSERT INTO payments VALUES ('a','i1',5000), ('a','i1',5000), ('b','i1',1000);
INSERT INTO alert_events VALUES ('a','i1','x'), ('a','i1','y');
WITH paid AS (
SELECT tenant_id, invoice_id, SUM(paid_minor) AS total_paid
FROM payments GROUP BY tenant_id, invoice_id
), alerts AS (
SELECT tenant_id, invoice_id, COUNT(*) AS alert_count
FROM alert_events GROUP BY tenant_id, invoice_id
)
SELECT i.tenant_id, i.invoice_id,
COALESCE(p.total_paid, 0) AS total_paid,
COALESCE(a.alert_count, 0) AS alert_count
FROM invoices AS i
LEFT JOIN paid AS p
ON p.tenant_id = i.tenant_id AND p.invoice_id = i.invoice_id
LEFT JOIN alerts AS a
ON a.tenant_id = i.tenant_id AND a.invoice_id = i.invoice_id
ORDER BY i.tenant_id, i.invoice_id;
Scroll sideways to view long lines.
Follow-up
- Why does SUM(DISTINCT amount) still give the wrong answer?
A PracHub practice schedule: complete one pair of related tasks per session and keep the result you can explain or run. Adjust the pace to your experience; this is not an employer hiring timeline.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Map the AP workflow
- Sketch import, validation and review. Mark two ways an incorrect record could change the result.
- Rehearse one project introduction and a question about the product.
Deliverable: A workflow sketch; A concise introduction
02Validate invoice amounts
- Run the money parser. Explain its rejection rules before adding cases.
- Group records with shared references across different tenants and suppliers.
Deliverable: A tested amount contract; A complete matching key
Practice prompt ↗Worked solution ↗03Reconcile repeated lines
- Compare repeated statement rows using counters and then sets. Explain the difference.
- Run the balance query with unpaid invoices, reversals and overpayments.
Deliverable: A mismatch example; Expected SQL results
Practice prompt ↗Worked solution ↗04Tell the correctness story
- Describe a correctness bug and the test that prevents its return.
- Draw the import transaction and checkpoint. Walk through a worker crash.
Deliverable: One evidence-backed story; A recovery walkthrough
Practice prompt ↗Worked solution ↗05Design review actions
- Model a stale review action and the conflict response.
- Reproduce the doubled total, then repair it without SUM(DISTINCT).
Deliverable: An API contract; A regression case
Practice prompt ↗Worked solution ↗06Query current review state
- Test resolved and reopened alerts with tied event timestamps.
- Explain one implementation to a reviewer. Address their strongest objection.
Deliverable: A latest-state query; A revised explanation
Practice prompt ↗Practice prompt ↗Practice prompt ↗07Prepare stakeholder examples
- Rehearse the disagreement and incident questions using real examples.
- Run every example and check the instructions from a clean directory.
Deliverable: Two concise stories; A reproducible handoff
Practice prompt ↗Practice prompt ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Use real project stories. Focus on your decision, the evidence available at the time and what changed afterward.
Explain a correctness decision
Task: Describe a real change where a plausible result was wrong. Explain the rule it broke, your correction and the user impact.
Approach
- Show the smallest input that exposed the bug.
- Explain your contribution and the regression check.
Follow-up
- What would you change if the issue had already reached users?
Discuss a disagreement about automation
Task: Explain a real disagreement about an automated action or release threshold. How did you reach a decision?
Approach
- Describe the competing risks and available evidence.
- State the decision, owner and outcome without overstating agreement.
Follow-up
- What result would have made you reverse the decision?
Hand off a data incident
Task: Describe an investigation another engineer had to continue. What helped them reproduce the failure while protecting customer information?
Approach
- Include the timeline, symptoms and current hypothesis.
- Provide sanitized evidence and a clear next action.
Follow-up
- How did you confirm the receiving engineer could continue?
- 01
Explain how another person could verify your result and what you did when the evidence changed.
Does this cover every Xelix engineering role?
No. It focuses on the advertised Python backend role. Other teams can have different requirements and assessments.
Xelix — Python Software Developer, Backend ↗Can I use AI to prepare?
The current posting permits research and preparation, but asks candidates not to generate answers with AI during live interviews. Practise explaining your work yourself.
Xelix — Python Software Developer, Backend ↗Are the eleven prompts actual Xelix questions?
They are original PracHub exercises informed by the backend role and accounts-payable product context. They do not establish a verified employer question bank.
Where can I run the SQL examples?
Use SQLite for the supplied fixtures. They check query results; PostgreSQL concurrency and production performance require separate testing.
PostgreSQL — Transaction isolation ↗Sources & methodology 8 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01Xelix — Python Software Developer, Backend ↗
Current backend responsibilities, desired technologies, typical stages and interview AI policy.
official · Accessed 2026-09-20 - 02Xelix — Accounts Payable platform ↗
Accounts-payable product overview.
official · Accessed 2026-09-13 - 03Xelix — Duplicate and incorrect payment protection ↗
Duplicate and incorrect-payment review.
official · Accessed 2026-09-20 - 04Xelix — Supplier statement reconciliation ↗
Statement-to-ledger comparison, discrepancies, missing invoices and credits.
official · Accessed 2026-09-20 - 05Xelix — Platform setup and security ↗
Public ERP integration and setup information.
official · Accessed 2026-09-13 - 06Python — Decimal arithmetic ↗
Decimal representation and precision for the money-parsing exercise.
official · Accessed 2026-09-13 - 07PostgreSQL — Transaction isolation ↗
Reference for transaction follow-ups.
official · Accessed 2026-09-13 - 08PracHub — Software Engineer practice ↗
Software Engineer questions across companies.
platform · Accessed 2026-09-13