2014–present
IAT Server
Three-tier, message-driven Spring application that deploys user-authored tests, administers them in the browser, stores encrypted results, and emits Excel workbooks that routinely exceed 150 worksheets.
JavaSpringJPA / HibernateMDBXSD / XJCXSLTAES-GCMMySQL
The problem
A desktop designer is useless without a server that can take a test package, turn it into HTML/JS, run sessions, and return results that remain unreadable even if the database is stolen.
Approach
- Message-driven beans for deploy, administration, and result services.
- Hibernate/JPA with domain logic inside persistence; polymorphic types via discriminator columns.
- 100+ complex types in XSD, XJC-generated POJOs completed with real behavior.
- XSLT pipelines: configuration XML → HTML + JavaScript; result streams → multi-sheet Excel.
- Data-at-rest: AES-GCM plus asymmetric encryption. Dual-support RSA and AES handshakes.
- Custom OAuth 2.0 provider with one-time auth codes, 20-minute access tokens, 14-day refresh.
- Linux administration. Public site in KnockoutJS + SCSS, proxied through nginx.
Results
- Results remain unreadable if the database is compromised.
- Homepage load dropped from eight seconds to two and a half.
- Source: github.com/mkjanda/IAT-Server.
IAT-Server on GitHubWebsite sourceiatsoftware.net
From the source
OAuth that owns its lifecycle
net.iatsoftware.iat.entities.OAuthAccess
@Entity
@Table(name = "oauth_access",
indexes = @Index(name = "oauth_access_ndx",
columnList = "access_token"))
public class OAuthAccess implements java.io.Serializable {
public static final int AUTH_TOKEN_CONSUMED = -4;
public static final int ACCESS_TOKEN_EXPIRED = -8;
public static final int accessExpiration = 1200; // 20 min
public static final int refreshExpiration = 86400; // 1 day
public OAuthAccess(Client c, IAT test,
String authToken, String accessToken, String refreshToken) {
this.client = c;
this.iat = test;
this.authToken = authToken;
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.refreshExpires = Calendar.getInstance();
this.refreshExpires.add(Calendar.DAY_OF_YEAR, 14);
}
}Custom OAuth 2.0: one-time auth codes, access tokens that expire in 20 minutes, refresh tokens that last 14 days. Indexed on access_token. Domain constants for every failure mode a client can hit.
Scoring that outlives the schema
IATResultSetNamespaceV1.cs
public class IATResultSet : INamedXmlSerializable
{
protected double _IATScore;
public void Score()
{
_IATScore =
(((mean6 - mean3) / sd3_6) +
((mean7 - mean4) / sd4_7)) / 2;
}
}
public class IATResultSetV3 : IATResultSetV1
{
public string Token { get; set; }
}Greenwald D-score lives in the V1 base. Later namespaces extend it for encryption and tokens so 2020 data scores the same way as 2026 data.