API stability
An honest description, for developers who depend on this library, of what is public API, what the version number means, and what may change.
The short answer
Section titled “The short answer”| Question | Answer |
|---|---|
| Do you guarantee backward compatibility? | No. The project does not aim for backward compatibility (a maintainer decision). Breaking changes can happen even within 1.x. |
| Then what does the version number mean? | Release order. Whether a release breaks something is told by the release notes, not by the number. |
| How do I use it safely? | Pin the exact version, read the release notes before upgrading, and follow “Using it safely” below. |
| What if the school changes something? | A daily check runs against the live school servers; when something breaks an issue is opened and fixed quickly. There is no time commitment (SLA). |
| Are the three languages the same? | Features, error codes, result fields and value rules are kept identical and tests enforce it. Naming style and a few language-specific features differ. |
Public API and internals
Section titled “Public API and internals”“Public API” is what gets a release-note line and a docs update (README, spec/) when it changes. “Internal” changes without notice.
| Language | Public API | Internal (do not use directly) |
|---|---|---|
| Python | The names in __all__ of the sejongpeia package: authenticate, authenticate_dhc, authenticate_sis, fetch_sis_business_periods, SejongAuthClient, SejongPublicData, the result and model classes, SejongAuthError, ErrorCode |
the modules and helpers in sejongpeia.common.*, sejongpeia.auth.*, sejongpeia.public_data.* (only the names imported with from sejongpeia import ... are public); names and arguments starting with an underscore (_session_factory, _clock) |
| Node | The functions, classes and types the package entry point (pro-sejongpeia) exports. The exports field of package.json opens only this one entry point |
everything the entry point does not export; options starting with an underscore (_sessionFactory, _nowMilliseconds) |
| Java | The public methods of auth.service.SuhSejongAuthEngine, auth.model.*, common.exception.*, publicdata.SejongPublicData and publicdata.model.*, common.util.SejongTlsSupport, common.config.SejongAuthProperties, the property prefix sejongpeia.* |
common.util.CommonUtil, the caller, mapper and fetcher classes in publicdata |
Java’s auth.client.* and auth.parser.* are public because using the library without Spring means building and wiring them yourself. Their constructor shapes can still change (semi-public). With Spring Boot auto-configuration you are not affected.
Even inside the public API, the following is outside the guarantee.
rawHtmlandrawJsonreturned by the raw option (include_raw,includeRaw,authenticateWithRaw): school text whose keys and structure follow the school. See Raw response and extra options.- Keys and values of
extra: they change when the school adds or removes a field.extrais only a way to reach fields the library has no name for. - Error message wording: always branch on the error code. (Error codes)
- Log wording, request order, internal cache implementation. The cache defaults are configurable and documented, but the implementation may change.
Version rule
Section titled “Version rule”- The current line is
1.x. The three languages (Java, Python, Node) share one version number. - The release workflow bumps the patch number (third digit) automatically. Minor and major are bumped by the maintainer by hand.
- The number does not follow the SemVer promise (patch is compatible, only major breaks). Behavior-changing changes can ship in an automatic patch release.
- Being at
1does not mean a stability declaration. - How breaking changes are announced: every release gets a one-line summary on GitHub Releases and in CHANGELOG.md, and a changed name or signature is stated in that line.
Renames and signature changes (method or field names, package paths, configuration keys) can land at once, with no compatibility alias. Expect that kind of change to be possible again.
What we still do
Section titled “What we still do”Compatibility is not promised, but we try not to surprise you.
- New features prefer adding (result fields, methods) over changing existing fields.
- When a name or shape must change, the three languages and the docs change in one PR.
- Changes that follow the school aim to keep your code working, but we cannot prevent the school data itself from changing.
What the three languages keep identical
Section titled “What the three languages keep identical”These must be the same in every language, and tests fail when they drift.
| Kept identical | How it is enforced |
|---|---|
| Request URLs, portal verdict to error code mapping and other shared values | spec/contract.json is the single source; each language’s contract test compares its constants |
The 10 error codes (AUTHENTICATION_FAILED, ACCOUNT_LOCKED, …) and their meaning |
spec/RESULT_SCHEMA.md, contract tests |
| Authentication result fields and meaning (only the spelling differs) | RESULT_SCHEMA, expected-value tests on the sanitized sample responses in spec/fixtures/ |
| The 15 public-data methods, their result fields and value rules (missing value is an empty string, failure isolation, cache) | spec/PUBLIC_DATA.md, one shared expected-result file (expected_public_data.json) compared in all three languages |
| Sources (authentication, public data) import only the common layer and never each other | dependency-rule tests (Python, Node, Java each) |
| Results against the real portal | a daily live login check in all three languages, field-by-field hash comparison (scripts/verify-live.sh) |
What differs by language is intentional.
- Naming: Python
snake_case, Node and JavacamelCase. Java names a few methods differently, as inauthenticate_dhc/authenticateDhc/authenticateWithDHC. The mapping is in Authentication methods. - Call style: Python and Java are synchronous, Node returns a
Promise. - Language-specific: Spring Boot auto-configuration and the
sejongpeia.*settings (Java),SejongTlsSupport(Java), the old codeINVALID_CREDENTIALS(kept only in Java, never thrown). - Date-time type: the authentication time uses each language’s own type.
Deprecation
Section titled “Deprecation”- A name we want to remove is kept for a while where possible, written up in the docs and release notes, and marked
@Deprecatedin Java. Example:SejongAuthErrorCode.INVALID_CREDENTIALSis no longer thrown but remains so existing code compiles. - No period is promised. Something can disappear or change without a deprecation marker. The release notes (see “Version rule”) are the only official signal.
School data is the school’s own text
Section titled “School data is the school’s own text”School fields in public data and authentication results are the strings the school returned, as is. The library carries no code tables or name mappings.
- Values such as department codes, organization names, cafeteria numbers, schedule titles and enrollment status labels change when the school changes them. Do not write code that branches on a list of values. For example
parentUnitNameis a label that changes each academic year and must not be used to decide authentication. - Date formats also differ per school source: the academic calendar uses
yyyy-MM-dd, the graduate calendarMM.dd. Each format is written on the Academic calendar page. - A missing value is an empty string. Public data never has
null; the SIS fields of authentication arenullwhen that lookup failed. - School fields the library does not map land in
extra; when the school adds a field it can show up inextrawithout a new release.
When the school changes something
Section titled “When the school changes something”- A check runs every day at 09:00 KST. The three languages really log in with a correct password (no wrong-password attempts), and the response shapes of the public data sources that need no account are verified. (Daily live portal check)
- When it detects a problem an issue is opened automatically.
- The contract documents (
spec/) and the three implementations are fixed in one PR and released.
Public data does not throw when one source fails: it returns the last cached value or an empty list. So an empty list cannot tell “no data” from “a problem on the school side”. Decide what it means on the calling side if that matters. (Failure isolation and cache)
Using it safely
Section titled “Using it safely”- Pin the exact version of the dependency. For example
pro-sejongpeia==<version>,"pro-sejongpeia": "<version>",kr.suhsaechan:sejongpeia:<version>, where<version>is the latest release number. A range (^,~=,+) takes breaking changes automatically. - Read the release notes before upgrading and run your tests first.
- Wrap the library in one thin adapter inside your app, so there is one place to fix when something changes.
- Branch on error codes, not messages.
- Do not hang core application logic on
extra, raw responses or school code values. - Usage examples are in the guides.
Changing this policy
Section titled “Changing this policy”If the policy moves toward promising backward compatibility, this document is updated first and the release notes announce it. Share opinions in Discussions or an issue.
