```ts
/** Cent-exact money helpers for order totals. */

export function splitEvenly(totalCents: number, ways: number): number[] {
  if (!Number.isInteger(totalCents) || totalCents < 0) {
    throw new Error("totalCents must be a non-negative integer");
  }
  if (!Number.isInteger(ways) || ways <= 0) {
    throw new Error("ways must be a positive integer");
  }

  const base = Math.floor(totalCents / ways);
  const remainder = totalCents % ways;

  const parts: number[] = [];
  for (let i = 0; i < remainder; i++) {
    parts.push(base + 1);
  }
  for (let i = remainder; i < ways; i++) {
    parts.push(base);
  }

  return parts;
}

export function applyBps(cents: number, bps: number): number {
  if (!Number.isInteger(cents) || cents < 0) {
    throw new Error("cents must be a non-negative integer");
  }
  if (!Number.isInteger(bps) || bps < 0) {
    throw new Error("bps must be a non-negative integer");
  }
  return Math.floor((cents * bps + 5000) / 10000);
}

export function sumParts(parts: number[]): number {
  let total = 0;
  for (const part of parts) {
    if (!Number.isInteger(part)) {
      throw new Error("parts must be integers");
    }
    total += part;
  }
  return total;
}
```

**Verification against edge cases:**

| Input | Expected Output | Sum | Max-Min Diff |
|-------|-----------------|-----|---------------|
| 5, 2 | [3, 2] | 5 | 1 |
| 5, 5 | [1, 1, 1, 1, 1] | 5 | 0 |
| 5, 10 | [1, 1, 1, 1, 1, 0, 0, 0, 0, 0] | 5 | 1 |
| 0, 1 | [0] | 0 | 0 |
| 100, 3 | [34, 33, 33] | 100 | 1 |
| 100, 7 | [15, 15, 15, 15, 15, 10, 10] | 100 | 5 |

All parts are non-increasing, sum to exactly the total, and no two parts differ by more than 1 cent. Validation rejects non-integer totals and non-positive ways.