What Is Due for Deletion and What Must Not Be Deleted
In one line
Personal information past its retention period must be deleted without delay, but a case under a retention order because of a dispute or a regulator's request must not be deleted even after the period passes. Turning the place where the two rules collide into data that can be judged is the whole of this job.
Why this was needed
With personal information, not deleting is an incident and deleting wrongly is an incident. If you do not delete, you violate what Article 21 of the Personal Information Protection Act says — destroy "without delay once the retention period has passed" — and conversely, if you erase the data of a claim in dispute, the company loses the means to prove its own position. Real incidents usually happen quietly on the latter side. A batch runs overnight and, only because "the period has passed," erases the documents of a case under mediation, and nobody knows it until the next month's mediation date.
There is one more element that makes the judgment hard. It is the basis date. The extinctive prescription of insurance is set by Article 662 of the Commercial Act, and in short, the right to claim insurance benefits and the right to claim a refund of premiums and reserves is 3 years, and the right to claim premiums is 2 years. But "3 years from when" is not automatically written in the data. The accident date, the claim closing date, or the contract end date? If systems use different days as the basis date, the same case is a purge target in one and still a retention target in another.
How it works
The design starts from putting four things in data.
- A retention period table. For each kind of target, write
기산일 이름,연수, and근거(the Korean words for basis date name, number of years, and legal basis). The reason to put the basis on the same line is that someone will surely show up later asking "why 5 years?" If you mix values that come from statutory prescription with values that come from company policy, you cannot tell what to fix when regulations change. - The basis date. For a contract, the contract date and the end date are the candidates, and for a claim, the accident date and the closing date. For a case that has not ended yet, the basis date does not exist — the prescription has not started, so if you treat such a case as "the date is empty, so very long ago," the data of claims in progress is erased entirely.
- A retention order (legal hold). You put on, per case, the reasons that require retention regardless of the period, such as a dispute, an investigation, or a regulator's request. The purge judgment is always done in the order "has the period passed?" and then "is an order in place?"
- Purge evidence. Leave what was deleted, when, and by which rule. What has been deleted cannot be shown again, so the fact of having deleted becomes the only evidence.
Date calculation has more traps than you might think. Python's datetime has no operation for "a few years later." timedelta is in days and seconds, so calculating with days=365*3 slips by a day across a stretch that includes a leap year. So for year-level addition and subtraction you use date.replace(year=...), and for a day that does not exist in that year, such as February 29, you handle it with an explicit rule. Even when calculating in SQLite, date(x, '+3 years') of the date and time functions normalizes a nonexistent date by rolling it over into the next month, so you must write down which way it was handled for the numbers of two systems to match.
기간 판정 ──▶ 보존 명령 제외 ──▶ 예행(dry-run) ──▶ 실제 파기 ──▶ 증적 ──▶ 남은 사본
What it looks like in the field
The incident seen most often is a moved basis date. The old regulation said "5 years from the contract date" and the new one says "5 years from the contract end date," but the batch was still using the old formula. For a 10-year contract the two values differ by 10 years, and thousands of records that must still be retained get erased. This incident shows itself only after the erasure.
The second is running a rehearsal and the real run with the same code. If you split them with a single flag, someday that flag gets set wrong. If you output the plan as a file and make the execution read that file, judge again, and only then delete, there is a place for a person to check in between.
The third is believing you have purged. You deleted the table rows but the attached files remain as they are, or you deleted in the production DB but it is still in the backup received yesterday. Deleting backups immediately is usually impossible, so at minimum you must reveal in a list what remains where and manage the handling schedule of that list separately. Without the list, the report "we deleted it" is not true.
What really matters in practice
- Rules as data. If you put the basis date name, number of years, and basis in a table, you can recompute. If it hides in code, nobody can verify.
- Fix the judgment order. Period → retention order → rehearsal → execution. If you change the order, what must not be deleted gets deleted.
- A case that has not ended has no basis date. Do not fill an empty date with 0 or a very old date.
- Leave the fact of deletion. Without evidence, you cannot even prove you purged.
- Count the remaining copies. Put even backups, exported files, and copies for analytics in the list.
What you will do in the next lab
You build a snapshot with 120 contracts, 240 claims, a retention period table, and retention orders, and count for yourself how many more purge targets appear if you change the basis date. You pull the cases whose period has passed, take out the cases under a retention order, output a rehearsal plan as a file, and then read that plan and actually delete. At the end you produce purge evidence, check that the contact details of the deleted people truly cannot be read from the remaining files, and reveal the copies left in the backup as a list.