diff --git a/sdk/java-sdk/.idea/gradle.xml b/sdk/java-sdk/.idea/gradle.xml
deleted file mode 100644
index 2a65317..0000000
--- a/sdk/java-sdk/.idea/gradle.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sdk/java-sdk/.idea/misc.xml b/sdk/java-sdk/.idea/misc.xml
deleted file mode 100644
index b9d0bed..0000000
--- a/sdk/java-sdk/.idea/misc.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sdk/java-sdk/.idea/vcs.xml b/sdk/java-sdk/.idea/vcs.xml
deleted file mode 100644
index fdf1fc8..0000000
--- a/sdk/java-sdk/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sdk/java-sdk/.idea/workspace.xml b/sdk/java-sdk/.idea/workspace.xml
deleted file mode 100644
index 8befbb3..0000000
--- a/sdk/java-sdk/.idea/workspace.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {}
- {
- "isMigrated": true
-}
- {
- "associatedIndex": 0
-}
-
-
-
-
-
-
-
- ",
- "kotlin-language-version-configured": "true",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "project.structure.last.edited": "모듈",
- "project.structure.proportion": "0.15",
- "project.structure.side.proportion": "0.2",
- "settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
- "vue.rearranger.settings.migration": "true"
- }
-}]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1738311656309
-
-
- 1738311656309
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/Main.java b/sdk/java-sdk/src/main/java/org/lightswitch/Main.java
deleted file mode 100644
index 0c9cbc8..0000000
--- a/sdk/java-sdk/src/main/java/org/lightswitch/Main.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.lightswitch;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println("Hello world!");
- }
-}
\ No newline at end of file
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/.gitkeep b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClient.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClient.java
new file mode 100644
index 0000000..081e273
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClient.java
@@ -0,0 +1,16 @@
+package org.lightswitch.sdk.client;
+
+import org.lightswitch.sdk.user.LightSwitchUser;
+
+public interface LightSwitchClient {
+
+ boolean getBooleanFlag(String key, boolean defaultValue, LightSwitchUser user);
+
+ int getIntFlag(String key, int defaultValue, LightSwitchUser user);
+
+ String getStringFlag(String key, String defaultValue, LightSwitchUser user);
+
+ void destroy();
+
+ boolean isEnabled(String key, LightSwitchUser user);
+}
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClientImpl.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClientImpl.java
new file mode 100644
index 0000000..4791fea
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/client/LightSwitchClientImpl.java
@@ -0,0 +1,92 @@
+package org.lightswitch.sdk.client;
+
+import org.lightswitch.sdk.exception.LightSwitchCastException;
+import org.lightswitch.sdk.model.FeatureFlag;
+import org.lightswitch.sdk.user.LightSwitchUser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class LightSwitchClientImpl implements LightSwitchClient {
+
+ // TODO develop FeatureFlagRepository, httpClient, SSEClient
+ private final Map featureFlags; // Mock
+
+ public LightSwitchClientImpl() {
+ // Mock data
+ this.featureFlags = new HashMap<>();
+
+ featureFlags.put("new-dashboard", new FeatureFlag(
+ "new-dashboard",
+ false, // default
+ Map.of(
+ Map.of("region", "US"), true // active "US" user
+ )
+ ));
+
+ featureFlags.put("beta-feature", new FeatureFlag(
+ "beta-feature",
+ false,
+ Map.of(
+ Map.of("plan", "premium"), true // active "premium" user
+ )
+ ));
+
+ featureFlags.put("discount", new FeatureFlag(
+ "discount",
+ 0, // default sale rates : 0%
+ Map.of(
+ Map.of("region", "US"), 100, // US user 100% sale
+ Map.of("region", "EU"), 50 // EU user 50% sale
+ )
+ ));
+ }
+
+ private FeatureFlag getMockFlag(String key) {
+ return featureFlags.get(key);
+ }
+
+ private T castValue(String key, Object value, Class expectedType) {
+ if (!expectedType.isInstance(value)) {
+ throw new LightSwitchCastException(key, value, expectedType);
+ }
+ return expectedType.cast(value);
+ }
+
+ @Override
+ public boolean getBooleanFlag(String key, boolean defaultValue, LightSwitchUser user) {
+ FeatureFlag flag = getMockFlag(key);
+ if (flag == null) return defaultValue;
+
+ Object value = flag.evaluate(user);
+ return castValue(key, value, Boolean.class);
+ }
+
+ @Override
+ public int getIntFlag(String key, int defaultValue, LightSwitchUser user) {
+ FeatureFlag flag = getMockFlag(key);
+ if (flag == null) return defaultValue;
+
+ Object value = flag.evaluate(user);
+ return castValue(key, value, Integer.class);
+ }
+
+ @Override
+ public String getStringFlag(String key, String defaultValue, LightSwitchUser user) {
+ FeatureFlag flag = getMockFlag(key);
+ if (flag == null) return defaultValue;
+
+ Object value = flag.evaluate(user);
+ return castValue(key, value, String.class);
+ }
+
+ @Override
+ public void destroy() {
+ featureFlags.clear();
+ }
+
+ @Override
+ public boolean isEnabled(String key, LightSwitchUser user) {
+ return getBooleanFlag(key, false, user);
+ }
+}
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/config/.gitkeep b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/config/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/config/LightSwitchConfig.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/config/LightSwitchConfig.java
new file mode 100644
index 0000000..ebae23c
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/config/LightSwitchConfig.java
@@ -0,0 +1,76 @@
+package org.lightswitch.sdk.config;
+
+import org.lightswitch.sdk.exception.LightSwitchConfigException;
+
+public class LightSwitchConfig {
+
+ private final String serverUrl;
+ private final String sdkKey;
+ private final int reconnectDelay;
+ private final int connectionTimeout;
+
+ private LightSwitchConfig(Builder builder) {
+ this.serverUrl = builder.serverUrl;
+ this.sdkKey = builder.sdkKey;
+ this.reconnectDelay = builder.reconnectDelay;
+ this.connectionTimeout = builder.connectionTimeout;
+ }
+
+ public static class Builder {
+ private String serverUrl;
+ private String sdkKey;
+ private int reconnectDelay = 5000;
+ private int connectionTimeout = 10000;
+
+ public Builder serverUrl(String serverUrl) throws LightSwitchConfigException {
+
+ if (serverUrl == null) {
+ throw new LightSwitchConfigException("Server URL cannot be null");
+ }
+
+ this.serverUrl = serverUrl;
+ return this;
+ }
+
+ public Builder sdkKey(String sdkKey) {
+ this.sdkKey = sdkKey;
+ return this;
+ }
+
+ public Builder reconnectDelay(int reconnectDelay) {
+ this.reconnectDelay = reconnectDelay;
+ return this;
+ }
+
+ public Builder connectionTimeout(int connectionTimeout) {
+ if (connectionTimeout < 0) {
+ //TODO automatic default setting log creation
+ return this;
+ }
+
+ this.connectionTimeout = connectionTimeout;
+ return this;
+ }
+
+ public LightSwitchConfig build() {
+ return new LightSwitchConfig(this);
+ }
+ }
+
+
+ public String getServerUrl() {
+ return serverUrl;
+ }
+
+ public String getSdkKey() {
+ return sdkKey;
+ }
+
+ public int getReconnectDelay() {
+ return reconnectDelay;
+ }
+
+ public int getConnectionTimeout() {
+ return connectionTimeout;
+ }
+}
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchCastException.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchCastException.java
new file mode 100644
index 0000000..bd4508b
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchCastException.java
@@ -0,0 +1,9 @@
+package org.lightswitch.sdk.exception;
+
+public class LightSwitchCastException extends RuntimeException {
+
+ public LightSwitchCastException(String key, Object value, Class> expectedType) {
+ super(String.format("Feature flag '%s' expected type %s but got value: %s (type: %s)",
+ key, expectedType.getSimpleName(), value, value.getClass().getSimpleName()));
+ }
+}
\ No newline at end of file
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchConfigException.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchConfigException.java
new file mode 100644
index 0000000..c0b7ea9
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/exception/LightSwitchConfigException.java
@@ -0,0 +1,12 @@
+package org.lightswitch.sdk.exception;
+
+public class LightSwitchConfigException extends Exception {
+
+ public LightSwitchConfigException() {
+ super();
+ }
+
+ public LightSwitchConfigException(String message) {
+ super(message);
+ }
+}
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/model/.gitkeep b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/model/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/model/FeatureFlag.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/model/FeatureFlag.java
new file mode 100644
index 0000000..5dbc6f6
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/model/FeatureFlag.java
@@ -0,0 +1,56 @@
+package org.lightswitch.sdk.model;
+
+import org.lightswitch.sdk.user.LightSwitchUser;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class FeatureFlag {
+
+ private final String key;
+ private final Object defaultValue;
+ private final Map, Object> filters; // filtering rules
+
+ public FeatureFlag(String key, Object defaultValue, Map, Object> filters) {
+ this.key = key;
+ this.defaultValue = defaultValue;
+ this.filters = filters != null ? filters : Collections.emptyMap();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
+ public Map, Object> getConditions() {
+ return Collections.unmodifiableMap(filters);
+ }
+
+ /**
+ * Find and return appropriate flag values based on user properties
+ */
+ public Object evaluate(LightSwitchUser user) {
+ for (Map.Entry, Object> entry : filters.entrySet()) {
+ Map conditions = entry.getKey();
+ boolean match = conditions.entrySet().stream()
+ .allMatch(cond -> user.getAttributes().getOrDefault(cond.getKey(), "").equals(cond.getValue()));
+
+ if (match) {
+ return entry.getValue();
+ }
+ }
+ return defaultValue;
+ }
+
+ @Override
+ public String toString() {
+ return "FeatureFlag{" +
+ "key='" + key + '\'' +
+ ", defaultValue=" + defaultValue +
+ ", filters=" + filters +
+ '}';
+ }
+}
diff --git a/sdk/java-sdk/src/main/java/org/lightswitch/sdk/user/LightSwitchUser.java b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/user/LightSwitchUser.java
new file mode 100644
index 0000000..d09e0a3
--- /dev/null
+++ b/sdk/java-sdk/src/main/java/org/lightswitch/sdk/user/LightSwitchUser.java
@@ -0,0 +1,38 @@
+package org.lightswitch.sdk.user;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class LightSwitchUser {
+
+ private final String userId;
+ private final Map attributes;
+
+ public LightSwitchUser(String userId) {
+ this.userId = userId;
+ this.attributes = new HashMap<>();
+ }
+
+ public LightSwitchUser(String userId, Map attributes) {
+ this.userId = userId;
+ this.attributes = new HashMap<>(attributes);
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public LightSwitchUser addAttribute(String key, String value) {
+ this.attributes.put(key, value);
+ return this;
+ }
+
+ public String getAttribute(String key) {
+ return attributes.get(key);
+ }
+
+ public Map getAttributes() {
+ return Collections.unmodifiableMap(attributes);
+ }
+}
diff --git a/sdk/java-sdk/src/test/java/org/lightswitch/sdk/client/LightSwitchClientImplTest.java b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/client/LightSwitchClientImplTest.java
new file mode 100644
index 0000000..5ad6ef1
--- /dev/null
+++ b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/client/LightSwitchClientImplTest.java
@@ -0,0 +1,78 @@
+package org.lightswitch.sdk.client;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lightswitch.sdk.exception.LightSwitchCastException;
+import org.lightswitch.sdk.user.LightSwitchUser;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LightSwitchClientImplTest {
+
+ private LightSwitchClient client;
+
+ @BeforeEach
+ public void setUp() {
+ client = new LightSwitchClientImpl();
+ }
+
+ @Test
+ public void testBooleanFlag_withMatchingCondition() {
+ LightSwitchUser user = new LightSwitchUser("user1").addAttribute("region", "US");
+ boolean flagValue = client.getBooleanFlag("new-dashboard", false, user);
+ assertTrue(flagValue, "US user must be returned TRUE flag for new-dashboard");
+ }
+
+ @Test
+ public void testBooleanFlag_withoutMatchingCondition() {
+ LightSwitchUser user = new LightSwitchUser("user2").addAttribute("region", "EU");
+ boolean flagValue = client.getBooleanFlag("new-dashboard", false, user);
+ assertFalse(flagValue, "EU user must be returned FALSE flag for new-dashboard");
+ }
+
+ @Test
+ public void testIntFlag_discount_US() {
+ LightSwitchUser user = new LightSwitchUser("user1").addAttribute("region", "US");
+ int discount = client.getIntFlag("discount", 0, user);
+ assertEquals(100, discount, "US user must be returned 100 flag for discount rate");
+ }
+
+ @Test
+ public void testIntFlag_discount_EU() {
+ LightSwitchUser user = new LightSwitchUser("user2").addAttribute("region", "EU");
+ int discount = client.getIntFlag("discount", 0, user);
+ assertEquals(50, discount, "EU user must be returned 50 flag for discount rate");
+ }
+
+ @Test
+ public void testIntFlag_discount_default() {
+ LightSwitchUser user = new LightSwitchUser("user3");
+ int discount = client.getIntFlag("discount", 0, user);
+ assertEquals(0, discount, "It must be return 0 which is default flag");
+ }
+
+ @Test
+ public void testCastException_onWrongType() {
+ LightSwitchUser user = new LightSwitchUser("user1").addAttribute("region", "US");
+ Exception exception = assertThrows(LightSwitchCastException.class, () -> {
+ client.getBooleanFlag("discount", false, user);
+ });
+ String expectedMessage = "expected type Boolean";
+ assertTrue(exception.getMessage().contains(expectedMessage));
+ }
+
+ @Test
+ public void testIsEnabled() {
+ LightSwitchUser user = new LightSwitchUser("user1").addAttribute("region", "US");
+ boolean enabled = client.isEnabled("new-dashboard", user);
+ assertTrue(enabled);
+ }
+
+ @Test
+ public void testDestroy_clearsFlags() {
+ LightSwitchUser user = new LightSwitchUser("user1").addAttribute("region", "US");
+ client.destroy();
+ boolean flagValue = client.getBooleanFlag("new-dashboard", false, user);
+ assertFalse(flagValue, "It must return default flag after destroy");
+ }
+}
\ No newline at end of file
diff --git a/sdk/java-sdk/src/test/java/org/lightswitch/sdk/config/LightSwitchConfigTest.java b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/config/LightSwitchConfigTest.java
new file mode 100644
index 0000000..b110634
--- /dev/null
+++ b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/config/LightSwitchConfigTest.java
@@ -0,0 +1,54 @@
+package org.lightswitch.sdk.config;
+
+import org.junit.jupiter.api.Test;
+import org.lightswitch.sdk.exception.LightSwitchConfigException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LightSwitchConfigTest {
+
+ @Test
+ void testValidConfig() throws LightSwitchConfigException {
+ LightSwitchConfig config = new LightSwitchConfig.Builder()
+ .serverUrl("https://api.lightswitch.com")
+ .sdkKey("test-key")
+ .reconnectDelay(3000)
+ .connectionTimeout(15000)
+ .build();
+
+ assertEquals("https://api.lightswitch.com", config.getServerUrl());
+ assertEquals("test-key", config.getSdkKey());
+ assertEquals(3000, config.getReconnectDelay());
+ assertEquals(15000, config.getConnectionTimeout());
+ }
+
+ @Test
+ void testDefaultValues() throws LightSwitchConfigException {
+ LightSwitchConfig config = new LightSwitchConfig.Builder()
+ .serverUrl("https://api.lightswitch.com")
+ .sdkKey("test-key")
+ .build();
+
+ assertEquals(5000, config.getReconnectDelay());
+ assertEquals(10000, config.getConnectionTimeout());
+ }
+
+ @Test
+ void testNegativeTimeoutUsesDefault() throws LightSwitchConfigException {
+ LightSwitchConfig config = new LightSwitchConfig.Builder()
+ .serverUrl("https://api.lightswitch.com")
+ .sdkKey("test-key")
+ .connectionTimeout(-5)
+ .build();
+
+ assertEquals(10000, config.getConnectionTimeout());
+ }
+
+ @Test
+ void testNullServerUrlThrowsException() {
+ Exception exception = assertThrows(LightSwitchConfigException.class, () ->
+ new LightSwitchConfig.Builder().serverUrl(null).sdkKey("test-key").build()
+ );
+ assertEquals("Server URL cannot be null", exception.getMessage());
+ }
+}
\ No newline at end of file
diff --git a/sdk/java-sdk/src/test/java/org/lightswitch/sdk/model/FeatureFlagTest.java b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/model/FeatureFlagTest.java
new file mode 100644
index 0000000..8ab9071
--- /dev/null
+++ b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/model/FeatureFlagTest.java
@@ -0,0 +1,54 @@
+package org.lightswitch.sdk.model;
+
+import org.junit.jupiter.api.Test;
+import org.lightswitch.sdk.user.LightSwitchUser;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class FeatureFlagTest {
+
+ @Test
+ public void testEvaluate_returnsVariantValue_whenConditionMatches() {
+ FeatureFlag flag = new FeatureFlag(
+ "discount",
+ 0,
+ Map.of(
+ Map.of("region", "US"), 100,
+ Map.of("region", "EU"), 50
+ )
+ );
+
+ LightSwitchUser userUS = new LightSwitchUser("user1").addAttribute("region", "US");
+ Object result = flag.evaluate(userUS);
+ assertEquals(100, result);
+
+ LightSwitchUser userEU = new LightSwitchUser("user2").addAttribute("region", "EU");
+ result = flag.evaluate(userEU);
+ assertEquals(50, result);
+ }
+
+ @Test
+ public void testEvaluate_returnsDefaultValue_whenNoConditionMatches() {
+ FeatureFlag flag = new FeatureFlag(
+ "discount",
+ 0,
+ Map.of(
+ Map.of("region", "US"), 100
+ )
+ );
+ LightSwitchUser user = new LightSwitchUser("user3").addAttribute("region", "EU");
+ Object result = flag.evaluate(user);
+ assertEquals(0, result);
+ }
+
+ @Test
+ public void testEvaluate_returnsDefaultValue_whenNoConditionsDefined() {
+ FeatureFlag flag = new FeatureFlag("new-dashboard", false, null);
+ LightSwitchUser user = new LightSwitchUser("user1");
+ Object result = flag.evaluate(user);
+ assertEquals(false, result);
+ }
+
+}
\ No newline at end of file
diff --git a/sdk/java-sdk/src/test/java/org/lightswitch/sdk/user/LightSwitchUserTest.java b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/user/LightSwitchUserTest.java
new file mode 100644
index 0000000..fe09558
--- /dev/null
+++ b/sdk/java-sdk/src/test/java/org/lightswitch/sdk/user/LightSwitchUserTest.java
@@ -0,0 +1,29 @@
+package org.lightswitch.sdk.user;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class LightSwitchUserTest {
+
+ @Test
+ public void testUserAttributesAdditionAndRetrieval() {
+ LightSwitchUser user = new LightSwitchUser("user1");
+ user.addAttribute("region", "US").addAttribute("plan", "premium");
+
+ assertEquals("US", user.getAttribute("region"));
+ assertEquals("premium", user.getAttribute("plan"));
+ }
+
+ @Test
+ public void testGetAttributesReturnsImmutableMap() {
+ LightSwitchUser user = new LightSwitchUser("user1");
+ user.addAttribute("region", "US");
+
+ Map attributes = user.getAttributes();
+ assertThrows(UnsupportedOperationException.class, () -> attributes.put("plan", "basic"));
+ }
+}
\ No newline at end of file