Skip to content

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.

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” 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.

  • rawHtml and rawJson returned 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. extra is 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.
  • 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 1 does 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.

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.

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 Java camelCase. Java names a few methods differently, as in authenticate_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 code INVALID_CREDENTIALS (kept only in Java, never thrown).
  • Date-time type: the authentication time uses each language’s own type.
  • A name we want to remove is kept for a while where possible, written up in the docs and release notes, and marked @Deprecated in Java. Example: SejongAuthErrorCode.INVALID_CREDENTIALS is 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 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 parentUnitName is 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 calendar MM.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 are null when that lookup failed.
  • School fields the library does not map land in extra; when the school adds a field it can show up in extra without a new release.
  1. 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)
  2. When it detects a problem an issue is opened automatically.
  3. 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)

  • 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.

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.